您好、欢迎来到现金彩票网!
当前位置:打鱼棋牌游戏平台 > 物理分页 >

内存管理与分页机制

发布时间:2019-08-19 08:09 来源:未知 编辑:admin

  我们经常会使用malloc()以及free()函数进行堆区内存申请与释放。那么你是否会这样做:

  我想很少有人这样做,因为除了喜欢“打破砂锅问到底”,或者经常使用测试一些特例的方法去学习的的人,一般人不会注意到这个问题到底是怎样的结果。

  在测试中我们可以看到,q指针指向NULL,所以对其取值会发生段错误,而对于p来说,虽然它申请了0字节的空间,但是free()释放以及取值时都不会发生段错误(读者可以拆开测试,否则有人会怀疑是free()引发的的段错误,而不是*q取q值时引发的段错误)。由此我们可以得知,malloc(0)分配的不是0个字节,p也不是指向NULL。那malloc(0)分配了几个字节?并且为什么*(p+1024)也不会越界发生段错误呢?这就是内存的分页机制与内存管理所决定。

  内存由于用途不同,分类也不尽相同,一般我们对于内存的分类也就这几种:栈区(stack area)、堆区(heap area)、全局区(静态区)(存放全局变量与静态变量static)、BSS段(存放未初始化的全局变量,未初始化的全局变量默认值为0)、文字常量区、数据区(data area)、代码区(code area)等。

  关于BSS段存储的未初始化全局变量的值,我们可以测试一下,如下(i为未初始化的全局变量,其值为0):

  我们可以查看/proc/pid/maps文件(pid表示以进程id号命名的文件名),其中有该pid的内存分配的详细情况。注意:proc下各个进程目录占磁盘大小都是0(读者可自行测试),因为其数据都存在于内存,该文件只是一个映射。实际不存在,如果该进程消亡,pid这个目录及其子目录将会消失。所以可以用循环测试,并且maps文件中的内存地址为已经映射了物理内存的虚拟内存地址。我们先运行程序,如下所示(获得当前进程pid为5052):

  每个进程都先天设定了4G的虚拟内存地址(不是真实的地址,只是一个编号)。虚拟内存开始时不对应任何内存,直接使用会引发段错误,不进入内核就接触不到物理内存地址,只会接触到虚拟内存地址。虚拟内存地址必须映射物理内存(或者硬盘上的文件)以后才能存储数据(数据存储在物理内存上,打印地址为虚拟内存地址)。而内存分配其实就是虚拟内存地址映射物理内存的过程,内存回收则是解除映射关系的过程。

  虚拟内存中,0~3G是用户控制,3~4G是内核空间。用户层不能直接访问内核层,可以通过Unix/Linux的系统函数访问内核层。我们通常所讲内存地址,其实都不是真正意义上的物理内存(PC机上内存硬件)的地址,而是虚拟内存地址。两个不同的进程,当其某个变量地址一样(虚拟),但是物理地址并不一样。

  映射关系如图所示(A、B进程均已映射物理内存,而C进程未映射物理内存,注意:虚拟内存一般并不会全部映射):

  由于两个不同进程有各自的虚拟内存,打印的进程1的内存地址为虚拟内存地址,而进程2的相同的虚拟内存地址,不能操作进程1的虚拟内存地址已映射的物理内存地址,并且进程2的*p并没有映射物理内存地址,所以进程2运行出现段错误。

  最小存储单位是一个字节(1B),最小管理单位是一页(4KB),虚拟内存地址连续时物理内存地址可以不连续,即使一次分配6000字节(不到两页也分配两页),两个内存页物理地址可能不挨着。多次申请内存时,如果之前分配的页内存没用完,则不再分配,除非之前分配的内存页用完才继续映射新的一页。getpagesize()可以获取当前内存页的大小。硬盘也是如此(硬盘上称为Block块):即使一个.txt文件中只有一个“a”字母,其大小为1B而其占用大小为4K。

  如图所示:test.txt文件中仅仅有14个’a’字符,但是现实其占用磁盘大小仍然是4K(一页)

  Windows下也有相同的机制(文件大小小于实际占用空间大小,占用大小是磁盘分块单位的整数倍):

  不可能进程每次申请一次系统就需要向其分配一次。(就像你和弟弟管妈妈要1块钱买辣条,你妈妈给了你俩十块钱说:“一周内都不要给我再要”,其实就算你一周内再向她要,妈妈也会给你,她只是不想你们俩不停地要而已,这就是管理(只不过我管我妈要1块,她好像给我5毛钱…….))。系统也是这样,它一次分配至少一页,在你(进程)没用完之前它都不会再给你分配,而当你用完分配的内存之后,就需要重新分配了。

  就拿malloc来说,第一次malloc(0)时一次性映射33个内存页(Redhat6.4),关于这点我们测试一下:

  只malloc()了一次,分配了33页,对前33页操作不会出错,但是一超过33页(p相对位置不为0,p+33*1024为虚拟地址的第34页)就产生了段错误,因为超过的虚拟内存地址并没有映射(分配)物理内存。

  例如:malloc(sizeof(int))申请了4字节,系统却给它33页,而malloc()给变量分配给变量内存时,除了数据区域外,还额外需要保存一些信息。底层有一个双向链表保存额外信息。malloc()给指针了12个字节,其中4个字节存放数据,另外8个存放其他信息或者空闲,如果将12个字节中前(低位)几个字节清空或者进行修改,free就可能出错,因为free只有首地址不能释放,还得需要额外附加信息(如malloc分配的长度)。(低八位是附加数据,高四位是int型数据)

  而p指向的地址为0X08fa9008(偏移了8个字节),直接指向高四位的4个字节(共12字节)。

  如果我们将低八位的数据进行清空或者修改(修改任意个字节),free就有可能失败,测试如下:

  摘要:本章首先以应用程序开发者的角度审视Linux的进程内存管理,在此基础上逐步深入到内核中讨论系统物理内存管理和内核内存的使用方法。力求从外到内、水到渠成地引导网友分析Linux的内存管理与使用。在...博文来自:的博客

  CPU是通过寻址来访问内存的。32位CPU的寻址宽度是0~0xFFFFFFFF,计算后得到的大小是4G,也就是说可支持的物理内存最大是4G。但在实践过程中,碰到了这样的问题,程序需要使用4G内存,而可...博文来自:坚持,让梦想闪耀!

  (一):进程空间在编程中,很多Windows或C++的内存函数不知道有什么区别,更别谈有效使用;根本的原因是,没有清楚的理解操作系统的内存管理机制,本文企图通过简单的总结描述,结合实例来阐明这个机制。...博文来自:Lixam的专栏

  内存管理是C++最令人切齿痛恨的问题,也是C++最有争议的问题,C++高手从中获得了更好的性能,更大的自由,C++菜鸟的收获则是一遍一遍的检查代码和对C++的痛恨,但内存管理在C++中无处不在,内存泄...博文来自:weixin_30359021的博客

  XV6分页机制、内存管理报告内容0.mmu.h的阅读mmu.h源码中给出了XV6虚拟地址的构成,及所代表的含义mmu.h中还有页表的相关信息,每个页目录都与1024条记录,每一个页表中也有1024条记...博文来自:的博客

  什么是内存分页?我们知道,CPU是通过寻址来访问内存的。32位CPU的寻址宽度是0~0xFFFFFFFF,计算后得到的大小是4G,也就是说可支持的物理内存最大是4G。但在实践过程中,碰到了这样的问题,...博文来自:Since_lily的博客

  作者:东方无敏() 标题:如何用一个最简单的方法去管理内存(含分页和分段机制) 基本上我们不需要理会IA32里的分段机制的,因为很多现代的CPU也不支持分段,例如ARM.至于在论坛

  操作系统——分页式内存管理为什么要引入内存管理?答:多道程序并发执行,共享的不仅仅只有处理器,还有内存,并发执行不过不进行内存管理,必将会导致内存中数据的混乱,以至于限制了进程的并发执行。扩充内存的两...博文来自:MISAYAONE的博客

  为什么要分页在保护模式中,内存访问使用分段机制——即amp;quot;段基址:段内偏移地址amp;quot;的方式,为加强段内存的安全性和可管理性还引入了段描述符的概念对段内存加强...博文来自:程序人生

  本文为第16章笔记因为段的长度不定,在分配内存时,可能会发生内存中的空闲区域小于要加载的段,或者空闲区域远远大于要加载的段.在前一种情况下,需要另外寻找合适的空闲区域;在后一种情况下,分配会成功,但太...博文来自:ProgrammingRing的专栏

  写在前面:分页机制完成线性地址到物理地址的转换80x86规定分页机制是可选的。分段和分页没有什么必然联系,分段可以说是Intel的CPU一直保持着的一种机制,而分页只是保护模式下的一种内存管理策略。想...博文来自:Tanswer_

  JVM优化之调整大内存分页(LargePage)本文将从内存分页的原理,如何调整分页大小两节内容,向你阐述LargePage对JVM的性能有何提升作用,并在文末点明了大内分页的副作用。OK,让我们开始...博文来自:chluknight的专栏

  工作中由于有时候项目中特殊业务需求,需要使用到内存分页,本人根据java.util.Arrays、lections工具类结合泛型标记写了一个简单的内存分页工具类,支持数组和L...博文来自:deb_ug的专栏

  (一):逻辑地址(LogicalAddress)     指由程式产生的和段相关的偏移地址部分。例如,你在进行C语言指针编程中,能读取指针变量本身值(&操作),实际上这个值就是逻辑地址,他是相对于你当...博文来自:HotIce0

  连续,设计简单,直接寻址,效率高。缺点:内存利用效率最低,有内部碎片。分页,设计最复杂,容易产生外部碎片,无论数据有多少,都只能按照页面大小分配,造成浪费。分段,程序员在编程和使用上多方面的要求,缺点...博文来自:郑学炜的技术博客

  Windows规定有些虚拟内存可以交换到文件中,这类内存被称为分页内存有些虚拟内存永远不会交换到文件中,这些内存叫非分页内存#definePAGEDCODEcode_seg(“PAGE”);//分页内...博文来自:Vinx Blog

  分页内存和非分页内存  首先介绍几个术语:进程上下文,就是表示进程信息的一系列东西,包括各种变量、寄存器以及进程的运行的环境。这样,当进程被切换后,下次再切换回来继续执行,能够知道原来的状态。中断上下...博文来自:蜗牛的专栏

  内存分段一个C编译器可能会创建如下段:,代码 全局变量 堆(内存从堆上分配) 每个线程使用的栈 标准的C库段式存储管理地址变换机构逻辑地址=段的基地址+段内地址程序中各个段对应的情况图内存分页基......博文来自:的博客

  一概述1.物理分页物理分页依赖的是某一物理实体,这个物理实体就是数据库,比如MySQL数据库提供了limit关键字,程序员只需要编写带有limit关键字的SQL语句,数据库返回的就是分页结果。2.逻辑...博文来自:MoveFlower的博客

  内存管理--三个地址,分页与分段的关系 (2012-03-2521:58:35)转载▼标签: 操作系统 分段 分页 控制寄存器 保护模式 it 逻辑地址 线性地址物理地址分类: 我的操作系统这里的三个...博文来自:haiross的专栏

  前面说道操作系统的每个进程都拥有自己的虚拟地址空间,对于这个32位操作系统,虚拟内存空间大小为4G。现代操作系统都使用分页来管理内存,把4G分成每一页为2^12=4K大小的页,一共有1M个的页(虚拟页...博文来自:u012138730的专栏

  386及更高型号处理器使用内存分页机制,这使得同一个线性地址可以被映射为多个物理地址,这种映射是通过分页单元这一特殊的硬件电路实现的。通常程序中所使用的线性地址是由链接器帮我们产生的,而操作系统通过维...博文来自:ars longa, vita brevis

  1.分段,分页机制 不分页:  线性地址  ==  物理地址分页:  线性地址  !=  物理地址线性地址空间也就是所有可能线性地址的范围.操作系统会在启动的时候测量到实际的内存有多少,  什么范围....博文来自:farmwang的专栏

  因为段的长度不定,在分配内存时,可能会发生内存中的空闲区域小于要加载的段,或者空闲区域远远大于要加载的段.在前一种情况下,需要另外寻找合适的空闲区域;在后一种情况下,分配会成功,但太过于浪费.为了解决...博文来自:baixiaoshi的专栏

  虚拟地址由操作系统维护,由MMU可以进行转换,扩大了内存空间分页管理。大多数使用虚拟存储器的系统都使用一种称为分页(paging)机制。虚拟地址空间划分成称为页(page)的单位,而相应的物理地址空间...博文来自:水木米

  内存寻址之分页机制/在上一篇文章Linux内存寻址之分段机制中,我们了解逻辑地址通过分段机制转换为线性地址的过程...博文来自:weixin_34095889的博客

  首先二层转发基于MAC地址转发,三层转发基于IP地址转发,但是不一意味着仅仅依靠IP地址就能转发,三层转发是建立在二层的基础上的,而仅仅依靠MAC地址是能够转发的。另外,由于二三层转发基于MAC地址、...博文来自:Apollon_krj的博客

  背景知识 逻辑地址:指程序的地址空间,与内存的真实物理地址无关。物理地址(绝对地址):是数据在内存中的实际地址。分页思想将进程的逻辑地址空间和真实内存地址空间划分为大小相等、固定的若干块。在进程中叫做...博文来自:swjtuzbko的专栏

  分段机制:  在8086时期,寄存器是16位,无法存放20位的物理地址,为了解决这问题,人们提出了分段机制,分段机制就是将内存分段,每段大小64kb(正好由16位表示),在段寄存器中放入段基址,然后+...博文来自:This is bill的专属博客

  前言上一篇我们了解了x86-16CPU计算机的内存访问方式,寻址方式,以及基于MS-DOS的应用程序的内存布局。这一篇会主要介绍32位处理器的内存访问,内存管理以及应用程序的内存布局。虽然目前64位C...博文来自:CC的技术专栏

  PAE分页模式可以将32位的线位的物理地址空间。相比于32位分页方式,其物理地址空间增加到了4PB。但对于在处理器上运行的任一进程而言,其最大的线GB。页面大小P...博文来自:huangkangying的专栏

  学习Linux中的大内存页hugepage。理解什么是“大内存页”,如何进行配置,如何查看当前状态以及如何禁用它。本文中我们会详细介绍大内存页hugepage,让你能够回答:Linux中的“大内存页”...博文来自:wang123459的博客

  利用CRC32绕过RAR密码(适合于小文本文件)原文标题:教你绕过rar密码文章仅作rar密码破解的探讨,如有高见还望提出。题目有点夸大其词,事实是我也没能想出一个更好的描述来总结这篇文章的内容,...博文来自:林毅洋

  最近比较有空,大四出来实习几个月了,作为实习狗的我,被叫去研究Docker了,汗汗!Docker的三大核心概念:镜像、容器、仓库镜像:类似虚拟机的镜像、用俗话说就是安装文件。容器:类似一个轻量级的沙箱...博文来自:我走小路的博客

  1.进程互斥定义:由于操作系统各进程需要使用共享资源,而这些资源需要排他性使用,各进程之间竞争使用这些资源,这些关系称为进程互斥。如:一个文件的读写问题。一个文件在被读的时候,不能同时进行写的操作。临...博文来自:Yates Law的博客

  HugePages大页内存知识点整理使用numactl来查看node0和node1上认领的cpu核数,以及内存资源.当然,首先确认下cpu是否是numa架构.查看系统所有节点的大页内存情况cat/sy...博文来自:脚踏实地,不断挑战自己极限,每天有收获就OK

  基址极限管理模式的问题:上篇博客分析了几种基本的内存管理模式:固定加载地址的内存管理,固定分区的内存管理,非固定分区的内存管理和交换内存管理。第一种只适合单道编程,后三种是多道编程均使用使用了同一种机...博文来自:genzld的博客

  近期公司老大让我研究大页内存,说是大页内存可以优化程序,让我根据dpdk来进行研究提升程序性能。前段时间研究dpdk中的各种机制,导致在这条路上走了许多的歪路,最后在开会的时候那么一说,卧槽,完全不对...博文来自:liyu123__的博客

  虚拟地址由操作系统维护,由MMU可以进行转换,扩大了内存空间分页管理。大多数使用虚拟存储器的系统都使用一种称为分页(paging)机制。虚拟地址空间划分成称为页(page)的单位,而相应的物理地址空间...博文来自:六芒星

  apollon_krj:你说的是“3、malloc(0)分配了多少内存?”上面那个测试例子吗?因为测试用例是int型,单位是四字节呀!

  yan822:博主 请问下,上面所说一页4k 为什么上面33页却是1024 * 33?

  u011560060:网上找了好多方法,几乎都千篇一律,问题还没解决,您这个方法帮助解决问题了,真是感谢!

http://lotusyogacenter.com/wulifenye/489.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有