操作系统内存管理

 

操作系统内存管理

一、  进程的虚拟地址空间

每个进程都被赋予自己的虚拟地址空间,对于32位进程来说,这个地址空间为 4G ,因此进程中的地址可以为0X000000000XFFFFFFFF之间的任何一个值。其中 4G 空间中的低区的 2G 空间留给进程使用,而高区的 2G 空间则留给系统使用。

Windows2000下,分区情况为:

1、   NULL指针分配的分区

NULL指针分配的分区占据0x000000000x0000FFFF,该分区的设置是为了帮助程序员掌握NULL指针的分配情况。例如当mallocnew分配失败时就返回NULL,该分区的地址是禁止进入的,访问该分区内的地址将发生访问违规现象,同时终止该进程的运行。

2、   用户方式分区

该分区是进程私有的地址空间,对于应用程序来讲,该分区是维护进程的大部分数据的地方,所有的.exedll模块均加载在这个分区,每个进程可以将dll加载到不同的地址中。对于.exe而言,一般加载到0x00400000地址处。

进程的栈和堆也是在该分区中开辟的。

3、   禁止进入分区

该分区是用户方式分区上禁止进入的分区,位于0x7FFF00000x7FFFFFFF,访问该分区的任何企图均将导致访问违规,该分区的存在是为了防止用户从用户区访问内核区的代码。如:

BYTE buf[70000];

DWORD numWritten;

WriteProcessMemory(GetCurrentProces(), (PVOID)0x7FFEEE90, buf, sizeof(buf), &numWritten);

将有可能成功地将数据写入只能有内核方式代码访问的内存。

4、   内核方式分区

该分区是存放操作系统代码的地方,用于线程调度、内存管理、文件系统支持、网络支持和所有设备驱动程序的代码全部在这个分区加载驻留在该分区的一切均可被所有近进程共享。

二、  虚拟内存的实现

本质上虚拟内存就是要让一个程序的代码和数据再没有全部载入内存的情况下运行程序。运行过程中,当执行到尚未载入的内存代码,或者要访问还没有载入到内存的数据时,虚拟内存管理器动态的将这部分代码或数据从硬盘载入到内存中。而且在通常情况下,虚拟内存管理器也会相应的将内存中某些代码或者数据置换到硬盘中,为即将载入的代码或数据腾出地方。

Win32中用来辅助实现虚拟内存的硬盘文件称为“调页文件”,调页文件用来存放被虚拟内存管理器置换处内存的数据,当这些数据再次被进程访问时,虚拟内存管理器会先将它们从调页文件中置换进内存,这样进程可以正确访问这些数据。

程序代码(包括exedll文件)不会被修改,所以他们所在的页被置换处内存时,并不会被写进调页文件中,而是直接抛弃,当再次被需要时,虚拟内存管理器直接从存放他们的exedll文件中找到他们并调入内存。

三、  虚拟内存的状态

近处虚拟地址空间中的页有三种状态:自由(free)、预留(reserved)和提交(committed)。

1、自由

自由表示此页尚未分配出去,可以用来满足新的内存分配请求。

2、预留

预留是指从虚拟地址空间中划出一块区域(页的整数倍大小),划出之后的区域中的页不能用来满足新的内存分配请求,只是用来供要求“预留”此段区域的代码以后使用,预留状态的区域并没有分配物理存储,只是增加了一个描述进程虚拟地址空姐使用状态的数据结构,用来记录这块区域已倍预留。

         3、提交

提交内存时会从调页文件中开辟空间,并修改VAD中的相应项。当然,此时并没有立刻从物理内存中分配空间,只是从磁盘的调页文件中开辟空间。

当有代码第一次访问这段提交内存中的某些数据时,系统发现并没有真正的物理内存,抛出缺页异常,虚拟内存管理器处理该异常,此时才会真正的分配物理内存。

四、  虚拟内存状态的管理

Win32虚拟内存管理器使用一个数据结构(Virtual Address Descriptor, VAD)来记录和维护每个进程 4G 的虚拟地址空姐的使用及状态,美国进程都有自己的VAD集合,这个集合被组织成一个自平衡二叉树。只有预留或提交的内存块才有VAD,自由的内存块没有VAD,因此不在VAD数据结构中的虚拟地址就是自由的。每块VAD数据结构记录了该块的起始地址以及当前状态。

五、  访问虚拟内存时的处理流程

对某虚拟内存区域进行了预留并提交之后,就可以对该区域中的数据进行访问了,一下为访问虚拟内存时的处理流程。

1、当被访问数据已在物理内存时,虚拟内存管理器只需记那个该数据的虚拟地址映射为物理指针。

2、当被访问的数据不在物理内存时,检测此数据是否在调页文件中或者在exedll文件中,若存在则进入下一步,否则发生访问违例错误,进程退出。

3、判断内存中是否有空闲页,若存在空闲页,则直接将调页文件或exedll文件的数据加载到该空闲页中。

         虚拟内存管理器维护了一个称为“页帧数据库page-frame database”的数据结构,该数据结构时操作系统全局的,当系统启动时被初始化,用来跟踪和记录物理内存真能干的每个页的状态。

4、当内存中不存在空闲页时,根据调页算法,首先选择出某个页作为换出页。

5、判断此页自上次调进后是否修改过,若没有被修改过,则将需要访问的数据调入此页,若被修改过,则需要先将此页的内容写到调页文件与此页相对应的备份页中,并随即将此页标记为空闲页。

六、  虚拟地址到物理地址的映射

当访问的数据已在物理内存中后,需要将虚拟地址转换为物理地址,即“地址映射”,才能真正访问此数据。

         每个进程都维护一套自己的层次表结构来实现地址映射。

第一层称为“目录表”,实际上是一个内存页,以四个字节为单元分成1024个项,每一项称为“页目录项”。

第二层称为“页表”,共有1024个页表,页目录表中的每个目录表项对应这一层中的某个页表,每个页表也占一个内存也,同样被分成1024项,表页的每一项称为“页表项”,每个页表项指向物理内存中的某一个页帧。

第三层称为页帧,是真正存数数据的地方。

当进行地址映射的时候,对应于层次表中的三个部分,页将32位的地址分成三个部分,最高的十位对应页目录下标,次高的十位对应页表的下标,低位的12位对应字节下标作为页内寻址。

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值