日期:2014-05-17  浏览次数:20596 次

Windows memory management study note(1)
32位Windows操作系统为每个进程提供了4GB的虚拟地址空间。
1.引入虚拟地址空间的原因
操作系统管理多个进程,存在多个进程同时访问同一物理地址的可能,通过引入虚拟地址来简化进程对于物理地址的操作。每个进程都拥有了独立的4GB的地址空间,而不会相互干扰。

2.方便虚拟地址空间的管理,Windows对虚拟地址空间进行了分区
NULL指针分区
  范围:0x0000 0000~0x0000 FFFF
  作用:防止内存被非法访问
  例子:分配内存时,如果由于某种原因分配不成功,则返回空指针0x0000 0000;当用户继续使用比如改写数据时,系统将因为发生访问违规而退出。

独享用户分区
  范围:0x0001 0000~0x7FFE FFFF
  作用:进程只能读取或访问这个范围的虚拟地址;超越这个范围的行为都会产生违规退出。
  例子:程序的二进制代码中所用的地址大部分将在这个范围,所有exe和dll文件都加载到这个。每个进程将近2G的空间是独享的。

共享内核分区
  范围:0x8000 0000~0xFFFF FFFF
  作用:这个空间是供操作系统内核代码、设备驱动程序、设备I/O高速缓存、非页面内存池的分配、进程目表和页表等
  例子:这段地址各进程是可以共享的


3.虚拟地址空间的映射方法——如何将虚拟地址空间映射为实际的物理地址
区域
  地址空间中的一片连续的地址。区域的大小必须是粒度(64k) 的整数倍,不是的话系统自动处理成整数倍。不同CPU粒度大小是不一样的,大部分都是64K。
  区域的状态有:空闲、私有、映射、映像。

物理存储器
  理论上32位CPU,硬件上只能支持4G内存的寻址内存分配的最小单位是4K或8K,一般来说,根据CPU不同而不同

页文件(虚拟内存)
  页文件是存在硬盘上的系 统文件,它的大小可以在系统属性里面设置,它相当于物理内存,所以称为虚拟内存

映射过程
  将虚拟地址空间的区域映射为物理内存地址和页文件地址的过程。
  注:对于应用程序而言页文件和物理内存之和是真正的可用物理内存总量。

页表
  为了有效的维护每个进程的4GB的地址空间,如果对一个4GB的内存的每一个32位地址进行直接管理那么需要4GB的空间进行维护。为了减少维护成本,系统对内存进行了分页管理, 将内存分解为4KB一页,页内再通过偏移量来查询。那么对于一个4GB的物理内存需要使用一个1MB * 32B的空间来管理所有的这些物理页面。这个4MB的物理地址页映射地址为页表

页目
  对于一个4MB的页表则需要使用4KB的页目进行维护。 页表同样进行分页管理,每页大小为4KB,那么需要使用1KB来管理这些页。

执行过程
如下一个32位的虚拟地址
高10位 中10位 低12位


高10位用于查询页目,中10位用于查询页表,低12位用于查询页内偏移量。
注: 2的10次方 = 1024, 2的12次方 = 4 * 1024 = 4KB。

系统读取到该地址后,使用高10位得到具体的页目地址,取出页目地址后取出得到页表中的页地址,然后使用中10位计算出页表中的偏移量取出物理页, 得到物理地址所在的页后,再使用低12位得到具体的偏移量。

其中页目中的32值,而其只需要使用其中的10就可以对所有的页表进行定位,所以页目中的其他多余的位用于表示页的状态
  例如
    1)当页目项第0位为1时,表明页表已经在物理内存中
    2)当页目项第7位为1时,表明这是一个4M的页面,这值已经是物理页地址,用虚拟地址的低22位作为偏移量

同样页表也只需要使用其中的20位就足以定位所有的1MB的物理内存页了,所以其他的位也被用于标记位
  例如 : 当页表项第0位为1时,表明访问的数据已经在内存中