二级页表

一级页表相当于把一本书缩小成几页的目录,通过目录来找书的内容。

但有个问题,如果书非常非常厚,有两本康熙字典那么大,目录也非常多,有一本高中教材那么厚。

那自然而然的,继续分呗,把高中教材那么厚的一级目录就当成一本教材书,再建立一次目录

二级页表由此诞生,就是把页表当数据,再建立页表

 

案例:

400MB的游戏程序载入了内存

32位系统,块大小固定为4K

则低12位一定是对应块大小的,高20位用于页表索引

400MB/4KB = 100K条,100K条索引,但页表的100K条中,每条32位占4B,所以页表总共就占了4B*100K=400KB的空间

那这400KB的页表也是要放在内存中的,内存一块是4KB,则实际在内存中要占用100块,或者叫100页

——————

但是100页有必要一次性装在进去吗?没必要

前面我们说,程序的数据是按需载入内存,不是一股脑全部塞进去,用不到的就先候着。而这100块或者叫100页其实对了400MB全部全部的数据。

正确的应该是先载入40MB数据,加载到某个地方还需要另外200M数据,再把200MB载入内存

而载入40MB的时候,需要载入总共100页中的10页,同理,再需要另外200MB时候,再对应载入50页。以此节省内存空间

——————

但是如何知道引入100块中的那几块呢?

有点递归的思想,把这100块页表数据看成另外某个程序的空间,也就是一个要占用400KB的程序。

400KB的程序,每块4KB,400KB/4K = 100条,100条索引每条32位占4B,所以页表(这里是页表的页表了)总共需要占用100*4B = 400B空间

400B作为页表也是要占空间的,一块是4KB,它只占了400B,也就是只占了一个最小单位 页的仅仅十分之一空间

——————

对比一下原来400MB的页表占用100页

现在400K(100页)的页表占用0.1页

 

好了,在极端情况下,32位操作系统内存最大4GB

4000MB的内存占满的情况下,页表占用1000页

4000KB(上面页表的1000页)的页表占用1页(刚刚好1页 4KB大小)

 

所以采用对页表再分页表的方法,撑死,在内存装满的情况下,顶级页表只需要占用1页而已。

这样,我们可以先把顶级页表全部装入,也就只占1页(一般都装不满),如有需要,再通过顶级页表按需载入二级页表,通过二级页表再引入程序的内容,这样就节省了不少空间

 

 

 

————————————

拓展到64位操作系统

64位,块大小依然是4KB

64位的低12位仍然不懂,对应4KB块大小。那高52位如何划分呢?

此时页表项因为不再是32位,一条占4B了,而是64位系统,页表的一条占用了8B

那么页表占用空间是:想要最多只用1页装入,4KB/8B = 2的9次幂,即为9位。因为妄想着最多只用1页索引,那么不可避免的就要反复建立多级页表了

最终就是:64=12+9+9+9+9+9+7

可以看到最终是6个级别的页表才分完

最后的7是没办法的事情,没有32位的极端情况下那么好运刚刚好只占1页