内存管理笔记七、页式内存管理

内存管理笔记七、页式内存管理

引言:内存管理就是要将各种媒介组建成一体,形成一个巨无霸似的虚拟存储系统。第六篇笔记,介绍了非固定分区内存管理方式,本篇笔记将分析其存在的问题,并就此引出页式内存管理。


      • 内存管理笔记七、页式内存管理
        • 一、Swap交换存在的问题
          • 1.1、大量的外部碎片
          • 1.2、地址空间增长困难
        • 二、分页内存管理引入
          • 2.1、Swap交换问题产生原因
          • 2.2、分页内存管理的机制
        • 三、地址翻译
          • 3.1、MMU的责任
          • 3.2、MMU的映射机制
          • 3.3、MMU的访问授权机制
          • 3.4、页表
          • 3.5、页面翻译事例
        • 四、分页系统的缺点及对应措施
          • 4.1、页表占内存空间大——多级页表
          • 4.2、访问速度降低——TLB缓存
          • 4.3、内部碎片的问题–Buddy
          • 4.4、共享困难——采用分段的内存管理
        • 五、其他一些问题讨论
          • 5.1、缺页中断
          • 5.2、锁住页面
          • 5.3、页面尺寸
          • 5.4、内存抖动

  在前面几篇笔记中,分别介绍了固定加载地址的内存管理(仅适用于单道编程)、固定分区的内存管理、非固定分区的内存管理和交换内存管理。固定分区的形式浪费内部的空间,造成内部碎片。非固定分区可以解决内部碎片,但是不利于程序增长。交换分区解决了程序增长,但也有外部碎片和空间增长困难的问题。

一、Swap交换存在的问题

1.1、大量的外部碎片

  随着程序在内存与磁盘间的交换,内存将变得越来越碎片化,即内存将被不同程序分割成尺寸大小无法使用的小片空间。这种散步在进程之间的闲置空间称为外部碎片,这是因为从进程的粒度来看,这种碎片处于进程空间的外面,这种碎片化的进程也称为”外部碎片化“。

  例如,我们运行8个程序,A、B、C、D、E、F、G、H,其启动、内存需要和交换过程如下:(偷懒直接截图啦)

内存管理笔记七、页式内存管理_第1张图片
图1、进程启动及切换过程

  在A~G,7个进程执行序列后,当前内存尚有200KB的闲置空间,分别处于地址1050KB ~1199KB和1550KB~1599KB。但因为不连续,所以无法容纳新的进程H,而进程H的空间需求只有200KB。随着进程的进进出出,外部碎片将浪费大量的内存空间。图2显示的是外部碎片化过程的示意图:

内存管理笔记七、页式内存管理_第2张图片
图2、交换系统中外部碎片的产生过程

1.2、地址空间增长困难

  除了外部碎片以外,交换的内存管理模式还存在着地址空间增长困难的问题:
1)、效率低下:指磁盘操作耗时,先将程序倒在磁盘上,再在内存寻找一片更大的空间将程序倒回来,这种做法效率低;
2)、交换能带来的空间增长有限:这个限制就是单一程序不能超过物理内存空间(减去操作系统占用部分)。

二、分页内存管理引入

2.1、Swap交换问题产生原因

  想解决Swap交换存在的问题,要需要分析其产生的根源是什么。空间碎片化的根源是每个程序大小不一样,这样在空间分配时存在不一致性。解决的办法自然是将空间按照某种大小进行分配,只要将虚拟内存和物理内存分成一样的部分,我们称为页,按也进行内存分配可以解决外部碎片问题。

  程序增长有限制是因为一个程序必须全部加在到内存才能运行,解决的办法就是使一个程序无需全部加载就可以运行,将需要的页面放在内存里,其他暂时不需要的页面放在磁盘上,这样一个程序同时占用内存和磁盘,其增长空间就大大增加了,若一个程序需要更多的空间,给其分配新页即可(不再倒出倒进,提高空间增长效率)。

2.2、分页内存管理的机制

  分页系统的核心就是将虚拟内存空间和物理内存空间皆划分为大小相同的页面,如4KB、8KB、16KB等,并以页面作为内存空间的最小分配单位,一个程序的一个页面可以存放在任意一个物理页面内。
  这样,由于物理空间是页面的整数倍,并且空间分配以页面为单位,将不会再产生外部碎片。同时我们可以允许一个进程的部分虚拟页面存放在物理页面之外,也就是磁盘上,可以解决程序比内存大的问题。可以通过分配额外页,解决程序空间增长问题。至此,交换系统存在的缺陷均被克服

三、地址翻译

  分页系统能够工作的前提是,对于任何一个虚拟页面,系统必须知道该页面是否在物理内存中,如果在的话,其对应的物理页面是哪个;如果不在的话,则产生一个系统中断(缺页中断),并将该虚拟页面从磁盘转到内存,然后将分配给它的物理页面返回。即页面管理系统要能够将虚拟地址转换为物理地址

内存管理笔记七、页式内存管理_第3张图片
图3、页面管理系统翻译过程

3.1、MMU的责任

  分页系统的核心是页面的翻译,即从虚拟页面到物理页面的映射。而这个翻译过程由内存管理单元MMU完成。MMU接收CPU发出的虚拟地址,将其翻译为物理地址后发送给内存。内存单元按照该物理地址进行相应的访问后,读出或写入相关数据。MMU同样提供硬件机制的内存访问授权。

内存管理笔记七、页式内存管理_第4张图片
图4、虚拟地址到物理地址的流向图

3.2、MMU的映射机制

  内存管理单元对虚拟地址的翻译只是对页面号的翻译,即将虚拟页面号翻译成物理页面号。而对于偏移值,则不进行任何操作。这是因为虚拟页面和物理页面大小完全一样,虚拟页面内的偏移值和物理页面的偏移值完全一样,因此无需翻译。

这里写图片描述
图5、虚拟地址构成

  那么内存管理单元是通过什么手段完成这种非线性的映射呢?是通过查页表对于每个程序,内存管理单元都为其保存一个页表,该页表存放的是从虚拟页面至物理页面的映射。每当一个虚拟页面寻找到一个物理页面后,就在页表里面增加一个记录来保存该虚拟页面到物理页面的映射关系,随着虚拟页面进出物理内存,页表的内容也不断变化。

内存管理笔记七、页式内存管理_第5张图片
图6、虚拟地址至物理地址的翻译过程

3.3、MMU的访问授权机制

  在程序发出一个虚拟地址给内存管理单元后,内存管理单元首先将地址里面页号部分字位分离出来,依据存储在页表里面的信息,判断该虚拟页面是否有效,是否存放在内存中,是否受到保护。完成相应的虚拟地址至物理地址的映射或者给出相关的判定信息。

非法虚拟页面:程序在加载前所使用的一切地址均是虚拟地址,即程序存在于虚拟空间。而虚拟空间的大小和系统的寻址长度有关,实际上大多数程序不会占满整个虚拟空间。这样,有一部分虚拟空间是没有使用的,即为非法虚拟空间。比如,一个程序的大小为100KB,如果试图访问100KB以上的地址,即视为非法访问。

3.4、页表

  页表的根本功能是提供从虚拟页面到物理页面的映射,因此,页表的记录条数与虚拟页面数相同。对于32位寻址的虚拟地址,如果页面数是4KB(占用12位),则虚拟页面数最多可以达到220,即1048576个虚拟页面,相关条数为1048576条。

  内存管理单元依赖页表来进行一切与页面活动有关的管理,包括判定一个页面号是否在内存里,页面是否受到保护,页面是否是非法空间等。因此页表除了提供虚拟页面至物理页面的映射,还包括记录这些信息。

这里写图片描述
图7、页表记录内容举例

3.5、页面翻译事例

内存管理笔记七、页式内存管理_第6张图片
图8、内存管理单元的虚拟页面到物理页面的翻译过程

  在该图中,CPU发出的虚拟地址是0010 000000000100,由于页面大小为4KB,后面12位为页内偏移值,前面4位为页面号。按此分解后,得到该地址在虚拟页面2,页内偏移值为4的地址上。将这两部分分开,以2为索引找到页表的第2个记录,发现该记录对应的物理内存页面号为110,即6。我们再将物理页面号和页内偏移值合并,得到物理地址为1100,000000000100.

四、分页系统的缺点及对应措施

  分页系统不会产生外部碎片,解决了进程空间的增长,但是其本身也存在如下一些问题:

4.1、页表占内存空间大——多级页表

  第一个缺点是页表很大,占用了大量的内存空间。如对于32位寻址的虚拟地址,如果页面数是4KB(占用12位),则虚拟页面数最多可以达到220,即1048576个虚拟页面,相关条数为1048576条。每个记录又要占多个字节,这样,一个页表所占内存空间很大。
  通常采用多级页表的方式,将页表分成一个个页面,不需要的页面也放在磁盘上,内存只放需要的页面。在多级页表结构下,页表根据存放的内容可分为:顶级页表、一级页表、二级页表等。一级页表存放二级页表的信息,二级页表存放三级页表信息,依次类推,最后一级页表才是虚拟页面到物理页面的映射。

内存管理笔记七、页式内存管理_第7张图片
图9、顶级页表存放次级页表信息

例如,如果采用两层页表的话,虚拟地址的前10位可作为顶级页表的索引,中间10位可作为次级页表的索引,最后12位可作为页内偏移值。如下图所示:

这里写图片描述
图10、两级页表下页表号和页内偏移值举例

这样,当CPU发出一个虚拟地址时,我们将虚拟地址一分为三,用最前面的10位找到顶级页表的对应记录,得到所需要的次级页表。用中间10位的值作为索引在刚才获得的次级页表找到对应的记录,得到对应的物理页面号。然后将物理页面号与页内偏移值连接起来获得最后物理地址。

4.2、访问速度降低——TLB缓存

  多级页表降低了内存占用空间,但是其同样降低了系统的访问速度,由单此内存访问变为多次内存访问,甚至需要加上磁盘访问,这样降低了地址翻译的效率。
  根据程序运行过程中呈现的时空局域性,即在一段时间内,程序要访问的地址空间有一定的空间局域性,如果一个页面被访问,则该页面的其他地址可能也会被访问,这样可将该页面的翻译结果存放在缓存中,提高系统的执行效率,这种存放翻译结果的缓存称为翻译快表TLB(Translation Look-Aside Buffer)。
  我们在TLB里面比较不是一个个的顺序比较,而是同时比较,即将所有的TLB记录与目的虚拟地址同时比较,因此一次检查就可以确定一个虚拟页面是否在TLB里。这种设计需要同时配备多套比较电路,其数目与TLB大小一样,这就是为什么TLB非常昂贵。linux系统采用三级页表,许多人未感觉到Linux慢,因为其TLB命中率高。

内存管理笔记七、页式内存管理_第8张图片
图11、Linux使用三级页表

4.3、内部碎片的问题–Buddy

  后面会单独写一篇关于Buddy算法,降低内部碎片浪费的笔记。

4.4、共享困难——采用分段的内存管理

  后面会单独写一篇分段内存管理的笔记。

五、其他一些问题讨论

5.1、缺页中断

  因CPU发出的虚拟地址对应的页面不在物理内存,就产生缺页中断,其处理步骤如下:

内存管理笔记七、页式内存管理_第9张图片
图12、缺页中断处理步骤

5.2、锁住页面

  若发生缺页中断,需要从磁盘上将需要的页面调入内存,如果内存没有多余的空间,需要在现有的页面选择一个页面进行替换,锁住页面,即保护重要的页面不被替换,需在页表相应记录里增加一项标志,若该标志设置,则页面置换算法会跳过该页。

5.3、页面尺寸

  分页系统需要考量的一个因素是页面应该设计多大,造成一个页面的绝大部分资源浪费,这种称为内部碎片。如果设计过小,则页表尺寸将增大,系统翻译速度降低。故需在二者间需求平衡,linux系统默认的页面大小为4KB。

5.4、内存抖动

  在更换页面时,如果更换的页面是一个很快就会被再次访问的页面,则在此缺页中断后,很快又会发生新的缺页中断。在最坏的情况下,每次新的访问都是对一个不在内存的页面进行访问,即每次访问都产生一个缺页中断,这样每次内存访问都变成一次磁盘访问,由于磁盘访问速度比内存慢一百万倍,因此整个系统的效率急剧下降,这种现象就称为内存抖动

参考资料:
《操作系统之哲学原理》 邹恒明著

纠错与建议
邮箱:[email protected]


你可能感兴趣的:(内存管理)