操作系统页表管理

原文地址:http://kdf5000.com/2017/03/12/操作系统页表的管理/

学过操作系统的都知道,在操作系统中存在一个虚拟内存的概念,它用于内存的管理,使得应用程序认为它有一段连续的内存,大大地简化了程序员码代码的难度。程序员只用关注在这个连续的虚拟内存段中怎么使用内存,不用关心在物理内存中到底用那一段内存,进程运行的时候操作系统会自动进行映射。操作系统是怎么做到的呢?实际上操作系统为每一个进程维护了一个从虚拟地址到物理地址的映射关系的数据结构,叫页表,页表的内容就是该进程的虚拟地址到物理地址的一个映射。

那么什么样的数据结构能够表示这个映射关系呢?最容易想到的方法就是用数组保存,虚拟空间中的每一个页都分配一个数组项。该数组指向与之关联的页帧, 但这会引发一个问题, 例如, IA-32体系结构使用4KB大小的页,在虚拟地址空间为4GB的前提下,则需要包含1048576
(4G/4K=1024*1024=1048576)项的页表,要寻址4G的空间,需要32位,也就是4Bytes, 1048576项需要4M(4 * 1024 * 1024 Bytes=4M)的内存.这个问题在64位体系结构下, 情况会更加糟糕. 而每个进程都需要自身的页表,这会导致系统中大量的内存都用来保存页表.

为了减少页表占用空间,我们可以考虑一个实际情况,对于一个进程的虚拟空间,其实大部分的内存都是没有使用的,因此在页表中其实是不需要这部分的映射的,因此前辈们设计出了多级页表的结构。

那么到底多少级才是最合适的呢?

页表级数的选择和发展

多级页表的设计思想其实就是现实生活中分组的概念,举个例子,我们研究中心有1000个人,现在秘书准备组织一次春游活动,需要统计一下有多少人去春游,如果秘书每个人都问一下记录一下每个人的信息,那么就需要1000行去记录这个信息,但是这样效率就很低而且浪费空间,所以秘书就让每个实验室单独统计,秘书只用要记录每个实验室去春游的人数以及负责人的联系方式即可,假设有五个实验室,则只需要五行即可,然后每个实验室的负责人统计一下自己实验室需要去的人员信息,那么这样效率就比较高了,而且因为只是记录了那些去春游的的人员信息,因此这样既提高了效率,也大大的也省了存储空间,当然你可能回发现一个小问题,如果10000个人都去那么实际上需要10005行统计信息,但是考虑到一些可能也是经常发生的情况,比如我们软件系统实验室春游那天需要加班赶项目,那么实际上我们实验室负责人就不用进行记录了,秘书那里直接记录软件实验室0个人去,甚至不记录也可以,所以一般情况下这样是可以提高效率,并且能够节省空间的。分级的本质其实也是将页表项进行分组管理,考虑到进程内存大部分空闲以及局部性,因此实际记录的时候大部分的记录是没有的,所以相比上面提到的直接使用一个数组(也就是一级页表)大大地节省了存储需要的空间。

我们再来算一笔帐,从Intel 80386开始,默认的页大小是4k, 提供32位的寻址空间。一页4k需要12位进行寻址,因此对于32的寻址空间,还有32-12=20位可以用来页表的索引。因为页表项存储的是物理内存一页的物理地址,因此一个页表项只能指向一页,而硬件的实现是使用CR3寄存器保存了页表的起始地址,因此对于页表我们应该使其只占用一页的内存。4k能够存储的页表项个数为4k/4B=1024, 寻址1024个索引只需要10位即可,因此在这个前提下,用于页表索引的20位自然而然的就分为了两段,也就是页表被分成了两级,十位用来表示一级页表内部偏移,十位用来表示二级页表的内部偏移,一级页表的页表项存储二级页表的物理地址。其实这也是Linux最初采用的两级页表分页机制。

Linux的两级分页机制

两级分页机制将32位的虚拟空间分成三段,对就是三段,低十二位表示页内偏移,高20分成两段分别表示两级页表的偏移。
二级页表.png
* PGD(Page Global

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值