探索windows虚拟内存

来源:互联网 发布:淘宝螺蛳粉哪家好 编辑:程序博客网 时间:2024/05/16 07:31

对于进程地址空间虚拟内存的使用,用户程序必须经过“保留(reserve)”和“提交(commit)”两个阶段才能使用一段地址范围。“保留一段地址范围”的用意是,将这段地址范围保留起来,但并不真正使用,由于这段地址范围不占用任何物理内存或其他外存空间,所以并不形成实质的开销。这对于有些需要连续的地址空间的程序有意义,他们可以在初始时保留一大段地址范围,以后需要的时候陆续使用。“提交地址范围”是指这段地址终究要消耗物理内存,由于windows支持物理内存与页面文件之间的交换,因此可提交的内存数量是,可用物理内存总量去除系统使用的物理内存数量后,再加上页面文件的大小。

在windows API中,应用程序通过VirtualAlloc或VirtualAllocEx来保留或提交地址范围;以后通过VirtualFree或VirtualFreeEx函数来解除已提交的地址范围,或者完全释放此地址范围。解除提交状态是指回到保留状态。因此,对于进程地址空间中的任何一个页面地址范围,它一定处于三种状态之一:空闲的、保留的、或已提交。

对于已提交的页面,系统会根据总的内存使用情况来调度它们。当物理内存紧张时,系统会选择一些页面,将它们换出到内存文件中,待下次使用的时候,再将它们换回来。通常情况下,应用程序并不需要干预系统的页面调度机制。在一些特殊情况下,应用程序也可以通过VirtualLock函数来锁住已提交页面,使得它们总是留在物理内存中;以后再掉用VirtualUnlock函数来结束这种锁定。

下面给出一个例子,来说明一些windows虚拟内存管理的一些问题。


输出结果全为0。

状态一:第一个system("pause")语句处,程序刚开始运行,还没有进行虚拟内存的分配操作。
状态二:第二个system("pause")语句处,已经保留并提交虚拟内存,提交大小已经变化,约增加了1G,但是内存(专用工作集),也就是进程正在使用的物理内存页面的数量并没有相应的增加1G,也就说当commit一段地址范围时,系统暂时也没有真正的分配物理内存页面。简单分析一下保留和提交系统所做的工作。虚拟地址空间的管理是通过VAD树和VAD位图,来记录虚拟地址段的状态。保留过程,系统根据虚拟地址空间的使用情况,查找一段符合条件的区间返回起始地址,并更新VAD树和VAD位图,现在不能访问,访问会发生访问违规。提交过程,记录物理存储器使用开销,分配设置PDE(页目录项)和PTE(页表项)属性。可以访问但是并没有分配物理页面给进程,访问发生页面错误时,页面处理例程进行实际的物理页面分配。
状态三:第三个system("pause")语句处,在每个页面都被访问过以后,根据页面错误数量可知,每次访问都发生了页面错误,页面错误处理例程分配了物理内存页面,所有当所有页面访问过之后,系统才给整个地址段分配了物理内存页面。
由输出结果可知,系统分配的页面都是初始化为0的。



原创粉丝点击