Windows x86 内存管理及分页机制

在如今的计算机体系结构中,如果直接让进程使用物理地址来访问内存,将使得进程的动态分配难以有效实施,因为进程直接使用物理内存的地址,因而,若要动态地申请内存和释放内存,也可能会使得进程中使用的内存可能会移动,这些都会受到限制。

若使用虚拟内存技术,可以给每一个应用程序都提供一个相对较大的内存区域,在windows x86的系统架构上,用户区域的内存可以达到3G,还可以对每个进程的数据进行保护,一个进程不能够通过猜测去直接访问到别的进程,还可以让程序员不去关心具体的硬件配置,如内存大小等。通过虚拟内存,可以让多个进程驻留在内存中,当内存资源不够时,操作系统可以利用磁盘资源来动态调用物理内存中的数据,只需要修改一个每个进程的内存映射即可达到对程序来说相对透明的效果。也可以利用映射来共享物理内存。

如下图为一级页表映射:

 

每个进程都拥有一个4G的虚拟内存,上图为访问1G时物理内存的图示。

每个进程都有一个页表,CR3寄存器里存的就是该进程页表的基址。当程序中使用一个32位的虚拟地址时,在一级页表分布的情况下,前20位即指定了在页表中的内存偏移,此时根据页表基址可以访问到该内存下的内容,该内容指定了想要访问的物理地址的页帧,因为物理地址也是按照每4K进行分页的,此时再根据虚拟地址后12位来确定想要访问的内存的偏移,再根据该得到的页帧地址,就可以访问到物理地址中的内容,进行可以对其进行操作了。

页表中的每一个页表项中,在不同偏移量(即前20位所指定的地址)下的内容有可能指向的为同一个物理地址的页帧,对用户来说,这种映射是透明的,在用户看来,他拥有了4G的内存空间。

因为程序中每一个地址值都有可能被引用到,所以页表项的个数要和虚拟地址页

的个数相同,即1M个,每个页表项都是32位的一个地址(虽然只有前20位有用),一共占用内存为4MB,这相对与稀缺的内存资源来说是相当巨大的,而虚拟内存中有很多内存都没有被使用,这就产生了浪费,故产生了二级页表的机制。

 

在二级分布机制中,一个32位的虚拟地址被分为了三段,前10位指向了页目录的偏移,加上CR3寄存器中记录的页目录的基址,可以很容易地找到一个页目录项中的内容,而页目录项中的内容即为一个32位的地址,该地址的前12位代表一个物理内存的页偏移,可以根据前20位准确得到想要索引的页表在物理内存的哪个页上,即页的基址,该基址即为页表所在的内存区域的基址,再根据32位的虚拟地址的中10位来确定偏移量即可得到页表项,该项的内容为一个32位的地址,即想要访问的物理内存的页基址(前20位有效),此时就确定到了物理内存的某个页面上,再根据32位虚拟地址的后12位确定偏移,即可访问到物理内存。

由于用户可能使用所有的虚拟地址,所以页目录项为,2的10次方(1024)个,每项占用4个字节,共4KB,每个页表也有(1024个)项,而多个页目录项的内容可以指向同一个页表,只有当用户申请的内存增加时才动态地增加更多的页表,这样就可以节省很多空间。

假如一个进程实际只用了4M内存,即物理地址的1024个页,用一个页表即可全部映射,此时用了一个页目录和一个页表,各占4K,共8K,若应用程序用了全部的4G空间,则需要2的20次方个页表和一个页目录,比一级分布机制仅多用4K的内存,而这种情况是不常见的。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值