操作系统 · 第 3 章

第 3 章 存储管理

逻辑/物理地址与重定位;分区分配三算法;页式地址变换计算(手把手例题);分页 vs 分段;虚拟内存与置换算法(缺页数对比例题)。

3.1 基本概念:逻辑地址与物理地址

存储层次访问流程图
图 3-1 CPU 取数据:寄存器 → Cache → 主存 → 外存逐级查找,命中即停

搞清"程序看到的地址"和"内存真实的地址"是两回事,本节就通了。

  • 逻辑地址(相对地址)——程序里用的地址,从 0 开始编号,是"程序眼里的世界"。
  • 物理地址(绝对地址)——内存条上真实的地址。
  • 地址重定位——把逻辑地址变成物理地址的过程。程序运行时由硬件(如页式的地址变换机构)动态完成, 所以叫动态重定位。
为什么需要它
  • 程序编译时不知道自己会被装到内存的哪一段;由操作系统在装载/运行时统一换算,程序才能"随便放"。

3.2 分区管理与分配算法

老式内存管理的做法,考"哪个算法找哪块"。

  • 固定分区——内存提前切成若干等长/不等长区,一区一程序。简单,但容易浪费(程序小、分区大)。
  • 可变分区——按需分配,用多少给多少。会产生"内存碎片"(离散的小空隙)。

空闲区分配算法的三个套路(名字—策略对照记):

算法怎么找特点
首次适应从低地址开始找第一个够大的简单快;低地址区容易磨碎
最佳适应找最小的够用块看似省,留下更多小碎片(最差策略名声)
最坏适应找最大的块切剩下的碎块还能用;大作业来了就没了
课堂练习(2 题)
  1. "找最小可用空闲区"是哪种分配算法? 答:最佳适应算法。
  2. 可变分区会产生什么问题?固定分区呢? 答:可变分区产生外碎片(分散的空闲小空隙);固定分区产生内碎片(分区内的浪费)。

3.3 页式管理:地址变换(计算题)★

"逻辑地址 = 页号 + 页内偏移"——软考最爱要求"算出物理地址"。

分页思想:把逻辑空间等分成页(大小固定,如 4KB),物理内存等分成同样大小的页框(块)。 程序的一页可以装到任意一个空闲页框里——内存利用率高,也没有外部碎片。

逻辑地址的结构:      [ 页号 P | 页内偏移 W ]
页表:每个进程一张,记录 "页号 → 页框号" 的对应关系

变换过程:逻辑地址 → 拆出页号P与偏移W → 查页表得页框号M → 物理地址 = M × 页大小 + W
页式存储管理的地址变换过程示意图
图 3-2 页式地址变换:页号查表换成块号,偏移原样保留
例题:手把手算一次

页面大小 4KB(4096 字节);逻辑地址 13000;该页在页表中的页框号为 8。求物理地址。

第 1 步:求页号与页内偏移
   页号 = 13000 ÷ 4096 = 3(整除部分)
   偏移 = 13000 − 3×4096 = 13000 − 12288 = 712

第 2 步:查页表,页号 3 对应的页框号 = 8(题给)

第 3 步:拼物理地址
   物理地址 = 8 × 4096 + 712 = 32768 + 712 = 33480
配套常识
  • 页大小是 2 的整数次幂时:页号=地址高位、偏移=地址低位(4KB → 低 12 位是偏移)。
  • 页表在内存里,由操作系统为每个进程维护;增加快表(TLB)可加速查表。
  • 分页解决的是"内存碎片和分配"问题;页是物理单位,对用户不可见。
课堂练习(3 题)
  1. 页面大小 1KB,逻辑地址 2500,页号和偏移分别是多少? 答:页号 = 2500 ÷ 1024 = 2;偏移 = 2500 − 2048 = 452。
  2. 上题若页号 2 对应的页框号是 5,物理地址是多少? 答:5 × 1024 + 452 = 5572。
  3. 页表的作用是什么? 答:记录逻辑页号到物理页框号的映射,供地址变换使用。

3.4 段式与段页式:分页 vs 分段

一张对比表搞定,考试就问"谁是逻辑单位、谁是物理单位"。

分页分段
划分依据物理单位,等长切分逻辑单位,按程序模块(代码段/数据段)划分,长度不等
对用户不可见(系统自动)可见(编写者划分)
地址结构页号 + 页内偏移段号 + 段内偏移
主要目的提高内存利用率、消除外碎片便于模块化、共享与保护

段页式 = 先分段(逻辑模块)再分页(物理存储):一个程序分成若干段,每段再分页。 地址变换要查两次表(段表 → 页表),最灵活但也最复杂。

课堂练习(2 题)
  1. 段的长度是固定的还是可变的?页呢? 答:段长可变(按逻辑模块定);页长固定(系统规定,如 4KB)。
  2. 段页式地址变换需要查几张表? 答:两张——先查段表找到该段的页表,再查页表找到页框。

3.5 虚拟内存与页面置换(计算题)★

页面置换算法 FIFO LRU OPT 逐格演示
图 3-3 FIFO / LRU / OPT 逐格走查:每列顶上标「缺」的就是缺页,最后数标记数
缺页中断处理流程图
图 3-4 缺页中断处理全流程:找块 → 脏页写回 → 调入 → 改页表 → 重新执行该指令

"内存不够用怎么办"——虚拟内存 + 置换算法。会数缺页次数就是分。

虚拟内存的思想:程序不必全部装入内存就能运行;只把常用部分放内存,其余留在磁盘。 访问的页不在内存时发生缺页中断,操作系统把缺的页从磁盘调入—— 如果内存满,还要先按置换算法淘汰一页。

三种置换算法
  • OPT(最优)——淘汰"未来最久不用"的页。理论最优,无法实现,作为标尺。
  • FIFO(先进先出)——淘汰最早进入的页。实现简单;可能发生 Belady 异常(帧变多反而缺页更多)。
  • LRU(最近最久未用)——淘汰过去最久没被访问的页。性能接近 OPT,硬件开销较大。
例题:数缺页次数(3 个页框)

页面访问序列:2, 3, 2, 1, 5, 2, 4, 5, 3, 2, 5, 2

FIFO 走一遍(淘汰"最早进入"的页):
  2 → [2]             缺
  3 → [2,3]           缺
  2 → 命中
  1 → [2,3,1]         缺
  5 → 淘汰2 → [3,1,5] 缺
  2 → 淘汰3 → [1,5,2] 缺
  4 → 淘汰1 → [5,2,4] 缺
  5 → 命中
  3 → 淘汰5 → [2,4,3] 缺
  2 → 命中
  5 → 淘汰2 → [4,3,5] 缺
  2 → 淘汰4 → [3,5,2] 缺
  → FIFO 共缺页 9 次(12 次访问,命中 3 次)

三种算法对比(同一序列、3 个页框):
  OPT 6 次  <  LRU 7 次  <  FIFO 9 次
结论:OPT 最优但不可实现;LRU 效果好;FIFO 最简单但最差。
几个配套概念
  • 缺页中断属于内部中断(软中断),不属于 I/O 中断。
  • 抖动(颠簸)——页面频繁换进换出,CPU 大部分时间在等页,效率骤降。
  • 局部性原理——程序一段时间内倾向于集中访问某些页,这是虚拟内存能快的基础。
课堂练习(2 题)
  1. 哪种置换算法可能发生 Belady 异常? 答:FIFO(增加物理块数反而可能增加缺页次数)。
  2. 缺页中断发生时操作系统要做什么? 答:把所需页面从磁盘调入内存;内存满时先按置换算法淘汰一页;调整页表后重新执行被中断的指令。