[操作系统] 内存管理策略:页式、段式、段页式

本文内容参考自《操作系统概念第七版》、《操作系统精髓与设计原理 原书第六版》

前言

为了解决外部碎片问题,一种可行的方案是允许物理地址空间为非连续的,具体的实现技术包括:分页、分段以及两者的合并段页式管理

页式

实现分页的基本方法涉及将物理内存分为固定大小的块,成为;而将逻辑内存也分为同样大小的块,称为。当需要执行进程时,该进程的页会被调入到可用的内存帧中。

  • 分页的硬件支持

[操作系统] 内存管理策略:页式、段式、段页式

CPU生成的每个地址分为两个部分:页号(p)和页偏移(d)。页号作为页表中的索引。页表中包含每页所在物理内存的基地址,这些基地址与页偏移的组合就形成的物理地址,就可交送给物理单元。


  • 内存的页模型

[操作系统] 内存管理策略:页式、段式、段页式


页大小是由硬件决定的,通常为2的幂。选择页的大小为2的幂可以方便地将逻辑地址转换为页号和页偏移。如果逻辑地址空间为2^m,且页大小为2^n,那么逻辑地址的高m-n位表示页号,而低n位表示页偏移。这样,逻辑地址可以表示为:

[操作系统] 内存管理策略:页式、段式、段页式


  • 举例说明页和帧(页框)的用法:

[操作系统] 内存管理策略:页式、段式、段页式

[操作系统] 内存管理策略:页式、段式、段页式

[操作系统] 内存管理策略:页式、段式、段页式


采用分页技术不会产生外部碎片,因为每个帧都可以分配给需要它的进程,不过分页有可能产生内部碎片,因为进程所需要的内存可能不是页的整数倍,那么最后一个帧就可能用不完。举个栗子更好说明~

页大小为2048B,一个大小为72776B的进程需要35个页和1086B,该进程就会得到36个帧,因此就有2048-1086=962B的内部碎片,最坏情况下,一个需要n页再加上1B的进程,需要分配n+1个帧,这样就几乎产生了一整个帧的碎片。


段式

采用分页内存管理有一个不可避免的问题:用户视角的内存和实际物理内存的分离。用户通常更愿意将内存看做是一组不同长度的段的集合,这些段之间并没有一定的顺序,如下图:

[操作系统] 内存管理策略:页式、段式、段页式

分段就是支持这种用户视角的内容管理方案,逻辑空间由一组段组成,每个段有自己的名称和长度。在段式管理策略中,地址指定了段号和段内偏移,因此用户通过两个量来指定地址:段号+偏移


  • 分段的硬件支持

[操作系统] 内存管理策略:页式、段式、段页式


  • 内存的段模型

[操作系统] 内存管理策略:页式、段式、段页式

每个进程通过维护一个段表来管理段式内存,系统也会维护一个内存中的空闲段列表,如上图所示,每个段表必须给出相应的段在内存中的起始地址,还必须指明段的长度,以确保不会使用无效的地址。


页式和段式的异同

  • 页式和段式管理策略都不会产生外部碎片,但都有可能产生内部碎片
  • 页的大小是统一的,而段的大小是可变的
  • 采用分页会导致用户视角的内存和实际内存的分离,即使用户视角的内存和实际物理内存不一样,而分段正好可以支持用户视角,使用户视角的内存和实际物理内存分布保持一致
  • 分页对程序员来说是透明的,用户指定一个地址,该地址通过硬件分为页码和偏移,这些程序员是看不见的;而分段对程序员来说通常是可见的,用户通过两个量:段号和偏移来指定地址,这两个量作为组织程序和数据的一种方便手段提供给程序员,程序员可以通过这两个量把程序和数据指定到不同的段(程序员必须清楚段的最大长度)