内存管理笔记九、段页式内存管理

版权声明:允许转载,请注明出处。 https://blog.csdn.net/XD_hebuters/article/details/79506062

内存管理笔记九、段页式内存管理

引言:在前面几篇笔记中,我们介绍到内存管理的多种方式,包括单道编程下固定加载地址,多道编程下固定分区非固定分区分页式内存管理,这些是内存管理模式不断演进的过程,本篇笔记将介绍现今广泛使用的段页式内存管理模式。至此,内存管理模式的演进基本就结束了,后面关于内存管理的笔记,将重在实践实现,包括虚拟内存性能调整、slab分配机制、buddy算法等学习。


一、分页式内存管理存在的问题

  我们在第七篇笔记,介绍了分页式内存管理,并分析了其存在的一些缺点及应对策略,包括多级页表克服页表过大、TLB缓存机制提高翻译速度、页面置换算法降低可能的缺页中断。那分页系统还存在什么其他缺陷吗?

1.1、共享困难

  虽然理论上可以按页进行共享,似乎单位很小,但实际上这是很难实现的,原因是一个页面的内容既可能包含代码又可能包含数据,即很难使一个页面只包含需要共享的内容或不需共享的内容。
  只要一个页面内有一行地址是不能共享的,这个页面就不能共享,这样想自由的共享任何内容就变得很困难。

1.2、程序大小受虚拟地址空间限定

  另外一个缺点也是分页系统无法忍受的,即一个进程只能占用一个虚拟地址空间。在这种限制下,一个程序的大小至多只能和虚拟空间一样大,其所有的内容都必须从这个共同的虚拟空间分配。

编译器的编译过程为例,其工作时需要维护多个数据结构:词法分析树、常数表、代码段、符号表、调用栈。这些数据结构可以增长和收缩,造成数据结构所需空间的变化。如果编译器只在一个虚拟地址空间中分配,那么必然发生不同数据结构占据虚拟空间不同位置的情况,当某个数据结构没有增长空间时,将导致编译失败。

这里写图片描述
图1、编译器的各个逻辑段在虚拟空间的示意图


二、段式内存管理

  由于分页系统只使用一个虚拟地址空间,其无法解决程序大小受虚拟地址空间限定的问题,故产生新的内存管理模式——分段管理系统。

1.1、分选的思想

  分段管理的思想,将一个程序按照逻辑单元分成多个程序段,每一个段使用自己单独的虚地址空间。这样就不会再发生空间增长时碰撞到另一个段的问题,从而避免因空间不够造成程序执行失败的问题。

同样以编译器分配虚拟地址空间为例,如下图2:

这里写图片描述

图2、给编译程序5个虚拟地址空间以解决空间增长困难问题

1.2、分段内存管理实现

  分段管理很像之前介绍的固定分区、非固定分区、交换等。只不过在基本的内存管理中,每一个程序只被分成一段,这里一个程序按照逻辑被分成多个段,故基本内存管理是分段管理的特例:只分一个段,下图3为二者的对比示意图:

这里写图片描述

图3、一段与多段内存管理的比较

  既然分段管理与前面的基本内存管理有着类似之处,那么其实现手段自然可以效仿,当程序只有一段(未分段),采用基址与极限的管理方式。当程序分为多个段,我们需要一组基址极限对。每一对基址极限用于其中一段的管理。如下图4所示:

这里写图片描述
图4、逻辑分段的管理机制是一组存放存放在段表里面的基址与极限

  在逻辑分段下,如果需要某一段,我们就用这一段的基址来搜索,依据段号来选择对应段的基址,再将段内位置偏移加到该基址上即可。如果偏差大于极限值,则算作出界。这样,每一个虚拟地址段可以加在到物理内存空间,我们只需在加载后将对应的基址寄存器与极限寄存器的值进行相应调整即可。

这里写图片描述

图5、段式内存管理虚拟地址至物理地址的映射过程

疑问:对于32位寻址的虚拟地址,在段式内存管理中,以5段为例,需要至少3位,如果段号占用寻址位数,那每个逻辑段实际并不能得到一个完整的虚拟地址空间?
计算数据:229 = 512M,这样失去了分段最初的初衷,查资料若想分配给逻辑段完整的虚地址空间,则可将虚拟段号存放在一个特殊寄存器里面,即不占用寻址字位,或者将其隐含在指令的操作码里面,依据操作码判断所属段号。

1.3、段式内存管理不足

  逻辑分段的优点十分明显:每个逻辑单元可以单独占用一个虚拟地址空间,这样使得编写程序的空间大为增长;其次由于是按照逻辑关系划分,共享起来十分方便;其上下文切换也很简单,段表很小,切换比较容易。

  分段管理的缺点也十分明显:既然是分段就存在基本内存管理存在的外部碎片和一个段必须全部加载进内存,另外一般一个程序的所有逻辑段是同时需要的,实行分段管理,由于每个段必须加载进内存,造成一个程序必须加载进内存,导致物理内存危机。


三、段页式内存管理

  针对分段存在的问题,我们的解决办法是分页,不过这次不是前面直接对程序进程分页,而是对程序里面的段进行分页,形成了所谓的段页式内存管理模式。写到这里莫名的激动呢。

1.1、段页式管理的思想

  段页式内存管理就是将程序分成若干个逻辑段,在每个段里面又进行分页,即将分段和分页组合起来使用。这样做的目的就是就是想同时获得分段和分页的好处,又避免了单独分页或者分段的缺陷。

1.2、段页式内存管理实现

  由于段页式管理模式是在段里面分页,而每个段占据一个虚拟地址空间,这就意味着一个程序将对应多个页表。那么一个程序如何管理多个页表呢?我们只需要将这些页表作为次级页表,在页表上面增加一层段表(相当于多级页表里面的顶级页表)。由段号在段表里面获得所应该使用的页表,然后在该页表里面查找物理页面号。其地址翻译过程如下图所示:

这里写图片描述

图6、段页式的页表管理与多级页表结构类似

  段表里面应该包含哪些内容呢?一般来讲包含的内容至少有段长、对应页表在内存的地址、页面大小、保护标志等等。


四、内存管理的演进过程

  至此,我们将内存管理演进过程,基本解释清楚了,其自身发展是一个不断优化的过程,在不断的否定中,内存管理的模式不断进步。

这里写图片描述

图7、纯粹分段 - 分页 - 逻辑分段 - 段页式的否定演变过程

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

纠错与建议
邮箱:db_hebut@163.com


没有更多推荐了,返回首页