说明:该系类文章更多的是从从哲学视角看 操作系统 这门学科。同时也是 操作系统的学习笔记总结。因为博主 这些年主要是以研究安卓系统和 嵌入式Linux为主,因此这个系类文章也是这两个领域不可或缺的基石之一,尤其是对操作系统感兴趣的伙伴可特别关注。
14 段式内存管理
14.1 分页系统的缺点
分页系统整体上是将交换系统的缺陷全部避免了;但是本身仍然有一些缺陷:
- 共享困难:一个页面只要有一行地址不共享,整个页面就是不共享的。
- 一个进程只能占用一个地址空间:即一个程序的大小至多只能和虚拟空间一样大。
要想满足上面两个要求,分页系统只用一个虚拟空间是解决不了这个问题的;因此需要新的管理模式:分段管理系统。
14.2 分段管理系统
分段管理:将一个程序按照逻辑单元分成多个程序段。每个段使用自己独立的虚拟地址空间。这样程序段就不会发生空间增长时碰到另一个段的问题(如果某个数据结构超过了虚拟地址的空间,程序执行仍会失败,但是这种概率已经很低了)。纯粹分段与逻辑分段比较如图所示:
- 纯粹分段:基本内存管理的一段式管理。
- 逻辑分段:一个程序分为多个段的分段管理。
在分段管理模式下,一个程序占据多个虚拟空间,一个虚拟地址将由段号和段内偏差两个部分构成。如图所示:
分段管理的实现手段:逻辑分段有多个段,因此需要一组基址与极限,如图所示:
在逻辑分段情况下,每个虚拟地址可以加载到物理内存中的任何位置,只需要将加载后的基址和极限寄存器做以下调整即可,如图所示:
如果需要某一段,就用这一段的基址来寻找,然后根据段号选择对应的段基址,将段内位移偏差加到基址上。翻译过程如下:
物理地址生成的过程如下所示:
整个过程中最重要的就是段表,和页表类似,但是由于段表很少,段的数量也很少,段的尺寸也很小。
注意:
- 段号也要占用寻址位,只是段数很小,所占的位数不会超过3位,每个逻辑段可以使用的空间很大,但是不是一个完整的虚拟空间。
- 如果想给一个段分配一个完整的虚拟空间,则将虚拟段号放在一个特殊的寄存器里面,即不占用寻址字位;或者将其隐含在指令的操作码里面(这样只要看到操作码就会知道所属段号)。
14.3 分段的优缺点
@1 逻辑分段的优点:
- 编写程序空间大幅度增长:每个逻辑单元可以独占一个虚拟空间。
- 共享方便:因为段是按逻辑关系来分。
- 分段管理节省大量空间:对于稀疏的程序,空闲部分不用分配虚拟空间。
- 上下文切换更加容易:因为段表很小。
@2 分段管理的缺点:
- 外部碎片和一个段必须全部加载到内存。
@3 对于缺陷的解决方法:
- 对程序中的段再进行分页,这样形成了段页式内存管理模式。
14.4 段页式内存管理
段页式管理:每个段分页;将分页和分段组合起来;同时获得分段和分页的优点,避免它们的缺点。(如果把每个段看做一个程序,则逻辑分段就相当于同时加载多个程序)
段页式内存管理的实现:由于段页式管理模式是在段里面分页,而每个段占住一个虚拟地址空间;因此一个程序将对应多个页表。在这里我们只需要将这些页表作为次级页表,而在次级页表上面增加一层段表(相当于多级页表里面的顶级页表)。由段号在段表里面获得所应使用的页表,然后在该页表里面查找物理页面号(由于TLB块表可以绕过段表和页表的查找,所以速度会加快),不过这里的快表必须将段号也包括进来,如图所示:
段表里面包含的内容随着系统的变化而变化,不过一般都大同小异,这里拿multics系统举例说明,段表记录的内容如图所示:
对应页表的地址、段长、页面大小、保护标志等前面已经进行过说明;对于是否分页标志,它是用来表明该系统是否分页。0值表示分页,l表示不分页;如果不分页,那就是纯逻辑分段,即Multies支持不分页的分段管理。而当前的商用计算机均支持段页式内存管理模式。
14.5 段号是否占用寻址字位
段号往往不占用寻址位,采用的是以下两种方式:
- 使用单独的寄存器来存放段号。
- 将段号隐含在指令操作码里。
如果地址完全是页号与页内偏差构成,则地址可以放在任何地方,采用段号的目的就是为了区分页表。
14.6 否定之否定的嵌套-纯粹分段与逻辑分段、分页与段页
从纯粹分段到分页、逻辑分段、段内分页的演变过程,流程如下:
- 人们根据直觉,将一个程序作为一整段来进行管理,从而形成了纯粹分段(固定加载地址、固定分区、非固定分区、交换)管理模式,也称为基本内存管理模式,这种模式由于直观,人人都能想到,曾经大为流行。
- 但纯粹的分段存在重大缺陷。由于此种模式下一个程序只有一段,从而导致内存空间增长困难、外部碎片、程序不能超过物理内存容量、一个程序必须同时加载到内存才能执行(除非使用重叠)等诸多缺点。为了克服这些缺点,我们引人了页式内存管理模式。
- 页式内存管理模式虽然克服了纯粹分段的一系列缺点,但又存在共享困难、一个程序只能在一个虚拟地址空间增长的问题。为了解决这个问题,我们引入了逻辑分段。逻辑分段是纯粹分段的否定之否定阶段。虽然都是分段,但已经不在一个层次上。逻辑分段将一个程序按逻辑关系分解为多个段,从而扩大了程序可以使用的虚拟地址空间并解决了共享难的问题。
- 但逻辑分段终究还是分段,自然又将分段的缺点引入。而要克服这些缺点,自然又想到了分页。这样我们就来到了段页式管理模式。
内存管理模式经历了两次互相穿插的否定之否定过程,如图所示:
这种方式推动了内存管理模式的进步。