408操作系统-分页存储管理
分页存储管理
分页存储是非连续内存分配方式的其中一种,是对连续分配存储的优化。
因为连续分配存储方式有些缺点:
- 分配给一个程序的物理内存是连续的
- 内存利用率低
- 有外碎片和内碎片的问题
非连续分配的优点:
- 一个程序的物理地址空间是非连续的
- 提高了内存利用率
- 允许共享代码和数据(共享库等)
- 支持动态加载和动态链接
一、基本分页存储管理(单级页表)
分页管理不会产生外部碎片
1.页面(页)
页面是进程的逻辑地址空间(虚拟内存空间)的划分,是逻辑地址空间顺序等分而成的一段逻辑空间,并依次连续编号,页面与页面之间是不一定连续的。
2.物理块(页框)
物理块则是对物理内存按顺序等大小的划分且物理块的大小与页面的大小一致。
物理地址空间与逻辑地址空间要想对应,就必须要一个中间人将它们关联起来。这个中间人就是页表。
3.页表
页表由多个页表项组成,一个页表项记录记录逻辑空间(虚拟内存)中每一页在内存中对应的物理块号。
页表是需要一直驻留在物理内存中的(多级页表除外),另外页表的起址和长度存放在 PCB(Process Control Block)进程控制结构体中。
总结:
一个用户程序被划分为一个一个的大小相等的页面,每个页面都有自己的逻辑地址。
通过逻辑地址访问对应的物理块时,分页地址机构自动将逻辑地址分为页号和页面地址(页内偏移量),ARM寄存器存放页表的首地址,通过首地址加上页号×页面大小(本质上也是偏移量)得到对应页表项的地址,页表项的物理块号加上页内偏移量即为最终地址。
页表也是存放在物理内存中的,查找一次页表就算是访问了一次物理内存。
通过页表中存放的物理块号,最终访问内存中的目标物理块(第二次访存)。因为进程在逻辑上是连续的整体,但实际上分页存储之后是离散的存放在物理块当中的。所以为了便于管理就创造了页表。
整个过程如图所示
二、二级页表
为什么要二级页表?
1.没有必要让整个页表常驻内存,因为进程在一段时间内可能只需要访问某几个特定的页面。
比如说,一个进程大小约为一万个页面,而实际执行时只需要几十个页面进入内存页框就可运行,若要求10个页面大小的页表必须全部进入内存,则相对实际执行时的几十个进程页面的大小来说,肯定降低了内存利用率。
从另一方面讲,这10页的页表项也并不需要同时保存在内存中,因为在大多数情况下,映射所需要的页表项都是在页表的同一个页面中。
2.使用多级页表之前,页表是连续存放的,因此当页表很大时,需要占用很多个连续的页框,虽然查询起来方便但对内存的要求太高,并且上面说过其中的大部分页面都是不会用到的。
如何理解二级页表工作流程?
使用二级页表,假如拥有220个连续页表项的页表可以被拆分成210个组(一个组大小为2^10个页表项),一个组的大小等于一个页框的大小,这些个组(也就是二级页表)都是离散存放在内存中的,提高了内存利用率。第一组叫做0号页表,以此类推到1023号页表。
为了管理这2^10个组,又建立了一个一级页表(一级页表是我个人的说法,学名叫:页目录表/顶级页表/外层页表)。一级页表项存放的物理块号指向了xx号页表的首地址 ,首地址再加上对应的二级页号*页面大小就找到了我们想要的二级页表项的地址,它存放的物理块号加上页内偏移量就对应了最终目标数据的物理地址。
那么一级页表在哪呢?原来它的首地址存放在ARM寄存器中。如果想找我们想要的一级页表项,也是首地址加上对应的一级页号*页面大小即可。
一个包含一级页号、二级页号、页内偏移量的逻辑地址项存放在一个页面中,这个页面在物理上对应一个页框/物理块,它们之间就是通过这个逻辑地址联系的,所谓页表就是一种联系手段。
二级页表的地址转换过程:
包含一级页号、二级页号、页内偏移量的项就是一个逻辑地址。一个进程的逻辑地址指向一个对应的物理地址。
首先,ARM寄存器存放了一级页表在内存中的首地址,加上一级页号×页面大小的值(页号实际上也是一种偏移量)找到对应的一级页表项,通过一级页表项的物理块号找到对应二级页表的首地址,加上二级页号×页面大小的值找到对应的二级页表项。通过二级页表项的物理块号找到对应的物理块的首地址,加上页内偏移量就是最终存放目标数据的物理地址。
下面是参考讲解视频,直接讲明白底层原理,看完直接秒懂。
二级页表的工作原理_哔哩哔哩
基本分页存储--单级页表_哔哩哔哩
访存次数(没有快表的情况下) :
一级页表 : 2次(找页表+找数据)
二级页表 : 3次(找页目录表+找页表+找数据)