在前面介绍分页的文章中,采用了一个32位机分页的例子,即把虚拟地址p的前20位作为页码,在页表中查询对应帧码。维护一个进程的页表就需要4M内存空间,该空间应是连续(为了在O(1)时间内查找),但有时候内存碎片较多,并不想在内存中分配4M这么多的连续地址空间,所以可以采用分层页表的方式。
分层页表
继续使用32位系统做例子,为了不使用4M那么多的连续地址空间,可以把一个页表再进行分块,一个页表中有220个条目,我们把他拆成210块,那么每块就有210个条目,这些块就可以分配到不连续的内存空间中,为了能找到每一块,就应该维护一个映射表,里面记录了每一块对应的基地址,称该映射表为外部页表,那么我们拿到一个虚拟地址p时,就先取高10位p[31:22],到外部页表中查找他对应那一块的基地址,再取中间10位p[21:12]作为基地址偏移,来访问记录该虚拟地址的页表,从而得到其对应的帧码,最后将帧码与低12位p[11:0]组合,即为真实物理地址。结构如下图
当系统为64位时,分层页表就不适用了,因为为了让每一级页表不能太大,就得分多层,因此访问一次物理地址需要访问多次页表,进行多次内存访问,这是不能接受的。对于64位系统,可以使用哈希页表,倒置页表等。
哈希页表
对于64位系统,当我们得到一64位虚拟地址p时,将前几位作为虚拟页码(前几位可能与页大小有关),计算虚拟页码的哈希值(哈希函数可能是取模吧),计算出哈希值后到哈希表对应条目进行查找,哈希表使用链表来解决碰撞问题,每个链表节点有3个内容,虚拟页码,映射的帧码,下一个节点指针。链表处理哈希碰撞的查找属于数据结构基础内容,不细讲了。查找到帧码后将其与页偏移组合,得到真实物理地址。
倒置页表
可以参考这篇文章,介绍很详细
倒排页表(inverted page tabe)
对于倒置页表来说,共享内存实现起来较为困难,书上介绍的是只允许页表包含一个虚拟地址到共享物理地址的映射。并没有理解这句话意思,希望有懂哥在评论区里解释一下,感谢