第8讲 物理内存管理II

物理内存管理 II:换页、页替换策略与工作集模型

《物理内存管理 I》讨论的是:当系统还有可用物理内存时,操作系统如何记录空闲页、分配连续页,并通过伙伴系统与 SLAB/SLUB 提高分配效率。

《物理内存管理 II》进一步讨论的是另一个问题:当物理内存不够用时,操作系统怎么办。

这一讲的核心不是“如何从空闲页中分配一个物理页”,而是:

  • 物理内存不足时,如何继续支撑程序运行;
  • 页不在物理内存中时,如何通过缺页异常恢复;
  • 内存满了时,应该换出哪个页;
  • 如何避免系统陷入频繁换页的颠簸状态;
  • 工作集模型如何帮助系统判断进程当前真正需要哪些页。

本讲主线可以概括为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
程序拥有虚拟地址空间

真实物理内存有限

OS 不一定让所有虚拟页同时驻留在物理内存

暂时不用的页可以换出到磁盘 Swap

再次访问时触发缺页异常

OS 将页换入物理内存并更新页表

内存满时需要页替换策略

策略不好或内存压力过大,会导致颠簸

工作集模型用于分析进程当前真正需要的页集合

❗ 核心结论: 物理内存管理 II 的核心是“物理内存不够时如何继续运行”:通过换页扩大可用虚拟内存,通过页替换策略选择牺牲页,通过工作集模型避免频繁缺页和颠簸。

1. 物理内存与磁盘:Swap 不是把磁盘变成内存

理解换页前,必须先区分物理内存和磁盘。

物理内存通常指 RAM,也就是常说的内存条。CPU 执行普通 load/store 指令时,最终访问的是物理内存中的数据。

磁盘包括 SSD、HDD 等外部存储设备。磁盘容量大、断电不丢失,但访问速度远慢于内存,CPU 不能像访问普通内存一样直接用地址访问磁盘内容。

对比项 物理内存 RAM 磁盘 / SSD / HDD
系统角色 主存 外存 / 辅助存储
访问速度 慢很多
CPU 是否能直接用普通内存指令访问 可以,经 MMU 翻译后访问物理内存 不可以,需要通过 I/O 路径访问
断电后是否保留 通常不保留 保留
换页中的作用 存放当前正在使用或可能马上使用的页 Swap 区临时保存被换出的页内容

因此,Swap 不是“磁盘变成了物理内存”。更准确地说:

1
2
Swap 区只是临时存放某些内存页内容的磁盘区域。
真正执行和读写时,数据仍然必须回到物理内存中。

可以用一个类比:

1
2
3
4
5
物理内存 = 办公桌
Swap 区 = 文件柜

CPU 只能直接处理办公桌上的资料。
如果资料在文件柜里,必须先拿回办公桌。

❗ 本节核心结论: 物理内存是 CPU 能直接访问的 RAM;磁盘是外存。Swap 只是把暂时不用的页内容放到磁盘,不能替代真正的物理内存访问。

2. 为什么需要换页机制

程序看到的是虚拟地址空间,而不是物理内存的真实容量。一个进程可能拥有很大的虚拟地址空间,但它并不一定会同时访问全部页面。

换页机制要解决两个典型问题。

2.1 物理内存超售

假设机器只有 4GB 物理内存,但有两个进程,每个都申请了 3GB 虚拟内存。

从虚拟地址空间角度看:

1
2
3
进程 A:3GB 虚拟内存
进程 B:3GB 虚拟内存
总虚拟内存需求:6GB

但物理内存只有:

1
4GB RAM

如果两个进程并不是同时访问各自全部 3GB,那么操作系统可以只让当前活跃页驻留在物理内存中,把暂时不用的页放到 Swap 区。

这使得:

1
虚拟内存总量可以超过物理内存容量。

但要注意,这不代表 6GB 内容能同时都在 4GB RAM 里。任意时刻真正能被 CPU 直接访问的,仍然只能是已经驻留在物理内存中的页。

2.2 按需分配

程序申请很大一段虚拟内存,但可能只使用其中一小部分。

例如:

1
2
3
char *buf = mmap(NULL, 1GB, PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
buf[0] = 'A';

程序申请了 1GB,但只访问第一个字节。如果操作系统立即为整个 1GB 分配物理页,会浪费大量内存。

因此,现代系统常采用按需分配:

1
2
3
4
5
6
7
先记录虚拟地址区域合法

不马上分配所有物理页

程序第一次访问某页时触发缺页异常

OS 再为该页分配物理页并建立映射

❗ 本节核心结论: 换页和按需分配让虚拟内存使用量可以超过物理内存容量,但真实执行时仍必须把被访问页放回物理内存。

3. 缺页异常:不一定是程序错误

缺页异常 Page Fault 的本质是:CPU/MMU 访问某个虚拟地址时,发现当前页表不能直接完成有效翻译,于是陷入操作系统处理。

缺页异常不一定代表程序出错。它可能有几种原因。

情况 是否一定是错误 说明
虚拟页合法,但还没分配物理页 不是错误 按需分配场景
虚拟页合法,但内容被换出到 Swap 不是错误 换页场景
虚拟地址不属于任何合法区域 是错误 可能导致 Segmentation Fault
权限不允许,例如写只读页 视情况而定 可能是非法访问,也可能是 COW

可以简化为:

1
2
Page Fault = 硬件发现无法直接完成地址翻译
Segmentation Fault = OS 判断访问非法后给进程的结果

不是所有 Page Fault 都会导致 Segmentation Fault。按需分配、换入换出、写时拷贝都可能以 Page Fault 作为正常处理入口。

这张图强调:缺页异常只是入口,操作系统还要判断这是合法缺页、换入请求,还是非法访问。


❗ 本节核心结论: 缺页异常不等于程序错误。它可能是按需分配、换页或 COW 等机制的正常控制路径。

4. 换页机制:把暂时不用的页放到 Swap

换页 Swapping 的基本思想是:

1
2
3
4
5
6
7
8
9
物理内存不够

选择某个暂时不需要的物理页

把它的内容写入磁盘 Swap 区

释放原来的物理页

把腾出来的物理页用于其他更紧急的虚拟页

4.1 换出

假设原来有映射:

1
虚拟页 V → 物理页 P3

当操作系统决定把这个页换出时,可能执行:

  1. 如果该页被修改过,将页内容写入 Swap 区。
  2. 在内核数据结构中记录:虚拟页 V 的内容现在位于 Swap 的某个位置。
  3. 修改 V 对应的页表项,使其不再指向可访问物理页。
  4. 回收物理页 P3。
  5. 清理或刷新可能存在的 TLB 缓存项。

换出后可以理解为:

1
虚拟页 V → Swap 区中的某个位置

此时虚拟页 V 仍然可能是合法虚拟页,只是当前不在物理内存中。

4.2 换入

之后程序再次访问虚拟页 V:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
CPU 访问虚拟页 V

页表项无有效物理页

触发 Page Fault

OS 发现 V 的内容在 Swap 区

分配新的物理页,例如 P7

从 Swap 读取内容到 P7

更新页表项:V → P7

返回用户程序继续执行

于是映射变化为:

1
2
3
换出前:虚拟页 V → 物理页 P3
换出后:虚拟页 V → Swap 区
换入后:虚拟页 V → 物理页 P7

这里有一个重要点:换入时不一定回到原来的物理页位置。

分页机制允许同一个虚拟页在不同时间映射到不同物理页。只要页表项更新正确,程序看到的虚拟地址可以保持不变。


❗ 本节核心结论: 换页不是移动虚拟地址,而是改变虚拟页背后的存放位置;换入后需要更新页表,使虚拟页指向新的物理页。

5. 换入位置改变时,页表如何改变

换入位置可能与换出前不同,这意味着虚拟页到物理页的映射必须更新。

例如:

1
2
3
4
5
换出前:
虚拟页 V → 物理页 P3

换入后:
虚拟页 V → 物理页 P7

实现这个改变的核心就是修改页表项。

换出前,页表项可以抽象为:

1
2
3
PTE(V):
valid = 1
physical_page = P3

换出后:

1
2
3
PTE(V):
valid = 0
swap_info = Swap 中的位置

换入后:

1
2
3
PTE(V):
valid = 1
physical_page = P7

同时还要处理 TLB。因为 TLB 可能缓存了旧的地址翻译结果。如果不清理,CPU 可能继续使用旧映射。

因此完整逻辑是:

1
2
3
4
5
6
7
修改页表项

使虚拟页指向新的物理页

刷新或失效相关 TLB 项

重新执行刚才触发缺页的指令

这体现了虚拟内存的一个基本能力:虚拟地址稳定,物理页可以动态变化。


❗ 本节核心结论: 换入位置改变后,OS 通过更新页表项中的物理页号来改变映射,并需要处理旧 TLB 项。

6. 按需分配的收益与代价

按需分配和换页机制都利用了一个事实:程序申请的虚拟内存,不一定会全部同时使用。

6.1 收益

按需分配的主要收益是节省物理内存:

1
2
3
没访问过的虚拟页

不占真实物理页

这可以让系统同时运行更多进程,或者允许进程拥有比物理内存更大的虚拟地址空间。

6.2 代价

代价是首次访问变慢。

第一次访问某个尚未分配或已换出的页时,需要:

  • 触发缺页异常;
  • 陷入内核;
  • 分配物理页或从磁盘读回;
  • 修改页表;
  • 恢复执行。

如果页面在 Swap 中,还涉及磁盘 I/O,延迟会明显增加。

6.3 缓解方法

操作系统会利用程序的局部性来缓解这一问题。

局部性 含义 对换页的意义
时间局部性 刚访问过的页,短期内可能再次访问 最近用过的页不应轻易换出
空间局部性 访问某页后,附近页可能也会被访问 可以考虑预取相邻页

因此,好的换页系统不会随便换出页面,而是尽量预测哪些页近期更可能被使用。


❗ 本节核心结论: 按需分配节省物理内存,但会增加首次访问或换入时的延迟;局部性是优化缺页成本的基础。

7. 页替换策略:内存满了应该换出谁

当物理内存不足时,操作系统必须选择某个页换出。这个选择规则就是页替换策略。

页替换策略回答的问题是:

1
内存满了,应该牺牲哪个页?

不同策略的差别在于:它们用什么标准判断“哪个页最不重要”。

本讲主要涉及:

  • MIN
  • FIFO
  • Second Chance
  • LRU
  • MRU

❗ 本节核心结论: 页替换策略的本质是在物理内存不足时选择牺牲页;策略好坏直接影响缺页次数和系统性能。

8. MIN:理论最优但现实不可实现

MIN 策略的规则是:

1
2
换出未来最长时间不会被访问的页;
如果某页未来再也不会被访问,就优先换出它。

例如当前内存中有:

1
2
内存页:1 2 3
未来访问序列:4 3 5 4 2 3

现在要访问 4,但内存满了,需要换出一个页。

观察未来:

1
2
3
页 1:未来不再访问
页 2:未来会访问
页 3:马上会访问

MIN 会换出页 1,因为页 1 未来不再使用。

MIN 的优点是理论缺页次数最少。它常用作评价其他策略的理想基准。

但它的问题也很明显:操作系统不知道未来。

现实系统无法提前知道精确的未来访问序列,所以 MIN 难以直接实现。


❗ 本节核心结论: MIN 是理论最优页替换策略,但依赖未来访问信息,因此现实系统通常无法直接实现。

9. FIFO:先进先出

FIFO 的规则非常简单:

1
谁最早进入内存,谁最先被换出。

它可以用队列实现:

1
2
队头:最早进入内存的页
队尾:最新进入内存的页

例如队列为:

1
队头 → [3][2][1] ← 队尾

需要换页时,FIFO 换出队头页 3。

新页进入后,加入队尾。

FIFO 的优点是简单,维护成本低。缺点是不考虑页面最近是否被访问。

例如某个页虽然很早进入内存,但最近一直被频繁使用。FIFO 仍然可能因为它“进来得早”而把它换出。


❗ 本节核心结论: FIFO 只看进入内存的时间,不看最近使用情况,因此简单但可能换出仍然活跃的页。

10. Second Chance:给 FIFO 一次保命机会

Second Chance 是 FIFO 的改进。

FIFO 的问题是太粗暴:只要一个页进入得早,就可能被换出。Second Chance 加入了访问位,用来判断队头页最近是否被访问过。

规则是:

1
2
3
4
5
6
7
查看队头页:
如果访问位 = 1:
清除访问位
将该页移到队尾
给它第二次机会
如果访问位 = 0:
换出该页

可以理解为:

1
2
FIFO 问:谁最早进来?
Second Chance 多问一句:你最近还用过吗?

示意流程:

Second Chance 比 FIFO 更合理,因为它避免立即换出最近被访问过的页。


❗ 本节核心结论: Second Chance 在 FIFO 基础上加入访问位,让最近访问过的页获得第二次机会,从而降低误换出活跃页的概率。

11. LRU:换出最近最久未使用的页

LRU 全称 Least Recently Used,规则是:

1
换出最近最久没有被访问的页。

它基于局部性原理:

1
2
最近使用过的页,短期内更可能再次使用;
很久没使用的页,短期内相对不重要。

例如链表记录页面最近使用顺序:

1
2
链表头:最久未使用
链表尾:最近使用

当前链表:

1
[2][3][1]

如果需要换出,LRU 换出链表头 2。

如果访问了 3,就把 3 移到链表尾:

1
2
访问前:[2][3][1]
访问后:[2][1][3]

LRU 比 FIFO 更合理的原因在于:

策略 判断标准
FIFO 谁最早进入内存
LRU 谁最近最久未使用

FIFO 不关心页是否仍然活跃;LRU 更接近程序的真实访问规律。

但真实系统中精确维护 LRU 可能有成本,因为每次访问都要更新时间顺序。因此实际系统常用近似 LRU 的方法,例如访问位、时钟算法等。


❗ 本节核心结论: LRU 根据“最近使用情况”判断牺牲页,更符合局部性原理;但精确实现可能成本较高。

12. MRU:换出最近刚使用的页

MRU 全称 Most Recently Used,规则与 LRU 相反:

1
换出最近刚被访问的页。

这听起来反直觉,但在某些访问模式下可能合理。

例如程序顺序扫描一个远大于内存的数据集:

1
1 2 3 4 5 6 7 8 ...

如果每个页只访问一次,最近访问过的页可能确实不会再用。此时换出最近刚访问过的页不一定差。

不过对于大多数具有时间局部性的程序,LRU 通常比 MRU 更符合直觉。


❗ 本节核心结论: MRU 适用于某些“访问后很快不再使用”的模式,但一般程序中 LRU 更常见、更符合局部性假设。

13. 几种页替换策略的对比

策略 换出标准 优点 缺点
MIN 未来最晚再访问或不再访问的页 理论最优 需要知道未来,现实不可实现
FIFO 最早进入内存的页 简单 可能换出活跃页
Second Chance FIFO + 访问位 比 FIFO 更关注近期访问 仍是近似策略
LRU 最近最久未使用的页 符合局部性 精确维护成本高
MRU 最近刚使用的页 特定顺序扫描场景可能有效 一般场景反直觉

可以把这些策略压缩成一句话:

1
2
3
4
5
MIN 看未来;
FIFO 看进入时间;
Second Chance 看进入时间 + 最近是否访问;
LRU 看最近一次访问距现在多久;
MRU 看谁刚刚被访问过。

❗ 本节核心结论: 页替换策略本质上都是在估计“哪个页未来最不可能被用到”,只是估计依据不同。

14. 好的换页策略能否降低颠簸

可以,但需要加一个限制。

好的页替换策略可以:

  • 减少不必要的缺页;
  • 避免换出马上要用的页;
  • 降低频繁换入换出的概率;
  • 减轻颠簸程度。

但它不能在所有情况下彻底消除颠簸。

颠簸的根本原因通常是:

1
2
3
所有活跃进程当前真正需要的物理页数量
>
实际可用物理页数量

也就是工作集总需求超过了物理内存承载能力。

如果系统内存严重不足,替换策略再聪明,也只能在有限空间里反复选择牺牲页。此时可能需要:

  • 减少并发进程;
  • 挂起部分进程;
  • 增加物理内存;
  • 降低程序内存需求;
  • 适当使用 Swap;
  • 必要时由 OOM 机制终止进程。

所以更严谨的说法是:

1
2
合适的页替换策略可以减少缺页次数,从而降低颠簸发生的概率和程度;
但如果活跃工作集总量超过物理内存容量,单靠替换策略无法根治颠簸。

❗ 本节核心结论: 好的页替换策略能减轻颠簸,但颠簸的根因是活跃页需求超过物理内存容量,不能只靠策略彻底解决。

15. 颠簸 Thrashing:系统把时间浪费在换页上

颠簸指的是系统频繁换入换出页面,以至于真正执行程序的时间很少。

典型现象是:

1
2
3
4
5
6
7
8
9
10
11
页刚换出,很快又要访问

触发缺页异常

页换入

为了腾空间,又换出别的页

别的页很快又被访问

继续缺页

系统进入这种状态后,大量时间消耗在:

  • 缺页异常处理;
  • 等待磁盘 I/O;
  • 换入换出页面;
  • 调度切换;
  • 维护页表和相关数据结构。

而用户程序本身推进很慢。

可以用图表示:

这就是电脑内存不足时“卡死”的本质之一:系统不是完全不工作,而是在大量做换页管理,真正执行用户程序的有效时间很少。

需要注意的是,颠簸时 CPU 利用率的表现可能复杂:

  • 有时 CPU 看起来利用率不高,因为进程大量阻塞等待磁盘 I/O;
  • 有时 CPU 也可能忙于内核态处理缺页、调度等工作;
  • 但无论哪种情况,系统有效吞吐都会下降。

❗ 本节核心结论: 颠簸是频繁缺页和换页导致的系统性能崩溃现象;大量时间用于换页和 I/O,而不是推进程序执行。

16. 工作集模型:判断进程当前真正需要哪些页

工作集模型用于分析一个进程在当前阶段真正需要哪些页面。

定义可以写成:

1
W(t, x) = 在时间区间 [t - x, t] 内被访问过的页集合

其中:

  • t 是当前时刻;
  • x 是观察窗口长度;
  • [t - x, t] 表示从过去某一时刻到现在的时间区间;
  • 在这个区间内被访问过的页,构成当前工作集。

直观理解:

1
2
3
最近一段时间用过的页

当前阶段还可能继续使用的页

这些页最好不要被轻易换出。否则可能马上再次访问,触发缺页,导致性能下降甚至颠簸。

例如:

1
2
3
4
5
时间窗口 [t - x, t] 内访问过:
页 1、页 3、页 5、页 8

则当前工作集:
W(t, x) = {1, 3, 5, 8}

如果一个页很久没有被访问,它就不属于当前工作集,可以成为换出候选页。

但要注意:

1
2
不属于工作集 ≠ 必定立刻换出
不属于工作集 = 可以考虑换出

❗ 本节核心结论: 工作集模型用最近一段时间访问过的页集合来近似进程当前真正需要的内存。

17. 工作集模型如何维护

工作集模型通常依赖访问位和时间信息。

一种简化维护方式是:

  1. 每个页有访问位。
  2. 硬件在访问页面时,将访问位置为 1。
  3. 操作系统周期性扫描页面。
  4. 如果访问位为 1,说明最近访问过,记录当前时间戳,并清除访问位。
  5. 如果访问位长期为 0,说明很久没被访问。
  6. 若当前时间与上次访问时间差超过窗口 x,则该页不再属于工作集。

可以表示为:

工作集模型的目标不是精确预测未来,而是利用过去一段时间的访问情况估计当前活跃页集合。


❗ 本节核心结论: 工作集模型通过访问位和时间窗口估计页面是否仍然活跃,帮助系统选择更合适的换出候选页。

18. 工作集模型与 LRU 的区别

工作集模型和 LRU 都利用“最近访问情况”,但它们不是同一种东西。

18.1 LRU 是替换策略

LRU 的问题是:

1
当前内存里的这些页中,哪一个最近最久没被访问?

它关注的是页面之间的相对最近访问顺序。

例如:

1
2
3
页 2 最久未使用
页 5 次久未使用
页 7 最近刚使用

LRU 会优先换出页 2。

18.2 工作集模型是内存需求模型

工作集模型的问题是:

1
2
某个进程在最近一段时间内到底用过哪些页?
这个进程当前正常运行大约需要多少页?

它关注的是一个进程的活跃页集合,而不只是单个页的替换顺序。

例如:

1
2
3
进程 A 当前工作集大小:100 页
进程 B 当前工作集大小:300 页
进程 C 当前工作集大小:200 页

如果总工作集大小超过物理内存容量:

1
100 + 300 + 200 > 可用物理页数量

系统就有较高风险发生颠簸。

18.3 对比表

对比项 LRU 工作集模型
类型 页替换策略 内存需求分析模型
关注对象 单个页的最近使用顺序 进程最近一段时间使用过的页集合
核心问题 换出哪个页 当前进程需要多少页
使用信息 最近访问顺序 时间窗口 [t - x, t] 内的访问集合
主要价值 选择较合适的牺牲页 判断活跃页集合,避免颠簸
局限 只看替换,不直接判断进程整体需求 需要选择合适窗口大小并维护访问历史

18.4 工作集模型相对 LRU 的优势

工作集模型的优势不是“每次都比 LRU 更会选某个页”,而是它能提供更高层次的信息。

优势一:判断进程整体内存需求

LRU 可以告诉系统:

1
哪个页最久没用?

工作集模型可以告诉系统:

1
这个进程当前大约需要多少页才能稳定运行?

优势二:帮助避免颠簸

如果所有进程的工作集总和大于物理内存,系统可以判断当前并发负载过高。

这时只靠 LRU 在各个页之间换来换去,可能仍然无法避免频繁缺页。工作集模型可以帮助系统考虑:

  • 是否减少并发进程;
  • 是否挂起某些进程;
  • 是否保护某些进程的工作集;
  • 是否避免换出最近活跃页。

优势三:更直接面向“保留活跃集合”

LRU 的动作是“选出最久未使用的页”。工作集模型的思想是“尽量保留当前工作集中的页”。

这更接近避免颠簸的目标。


❗ 本节核心结论: LRU 是具体页替换策略;工作集模型是分析进程当前活跃页集合的模型。工作集模型能为页替换和避免颠簸提供更高层次参考。

19. 一个完整例子:从缺页到换入再到工作集判断

假设一个程序有 5 个虚拟页:

1
V1 V2 V3 V4 V5

但系统只能给它 3 个物理页。

当前物理内存中有:

1
2
3
V1 → P1
V2 → P2
V3 → P3

现在程序访问 V4。

19.1 触发缺页

因为 V4 当前不在物理内存中:

1
2
3
4
5
访问 V4

页表无有效映射

Page Fault

19.2 系统选择换出页

物理内存满了,需要选择牺牲页。

如果使用 FIFO,可能换出最早进入内存的 V1。

如果使用 LRU,可能换出最近最久未访问的页。

如果使用 Second Chance,会先检查队头页最近是否被访问过。

19.3 换出与换入

假设系统最终选择换出 V1:

1
2
3
4
5
V1 内容写入 Swap
释放 P1
从磁盘或文件中准备 V4 内容
把 V4 放入 P1 或其他空闲物理页
更新页表:V4 → P1

如果后续 V1 又马上被访问,系统又会触发缺页并把 V1 换入。

如果这种情况不断发生,就可能颠簸。

19.4 工作集分析

如果最近时间窗口 [t - x, t] 内程序频繁访问的是:

1
V1 V2 V3 V4

则工作集大致是:

1
W(t, x) = {V1, V2, V3, V4}

工作集大小是 4 页,但系统只给了 3 个物理页。此时无论替换策略怎么选,都可能频繁缺页。

这说明问题不只是“换出哪个页”,而是“这个进程当前需要的页数已经超过系统给它的物理页数”。


❗ 本节核心结论: 页替换策略解决“换谁”,工作集模型进一步揭示“当前给的物理页够不够支撑进程活跃集合”。

20. 常见误区总结

20.1 Swap 不是物理内存

Swap 在磁盘上,不能像 RAM 一样被 CPU 直接访问。页内容在 Swap 中时,必须先换入物理内存,程序才能继续访问。

20.2 被换出的是页内容,不是物理地址

更严谨的说法是:

1
2
3
虚拟页对应的内容被写到 Swap;
原物理页被释放;
以后换入时可能使用新的物理页。

不是“物理地址被 swap 出去了”。

20.3 缺页异常不一定是非法访问

合法虚拟页尚未分配物理页、或者已被换出到 Swap,都会触发缺页异常。只有操作系统判断访问非法时,才会导致 Segmentation Fault。

20.4 好策略不能根治内存严重不足

页替换策略可以减少缺页,但如果所有进程工作集总量超过物理内存容量,仍可能发生颠簸。

20.5 工作集清出不等于立刻换出

一个页不属于工作集,表示它可以成为换出候选,不代表它一定马上被换出。

20.6 LRU 和工作集模型不是同一层概念

LRU 是页替换策略;工作集模型是内存需求分析模型。二者都利用最近访问情况,但解决问题的层次不同。


❗ 本节核心结论: 本讲最容易混淆的是“Swap 与物理内存”“Page Fault 与 Segmentation Fault”“页替换策略与工作集模型”这几组概念。

21. 自测题答案修正版

题 1:为什么说换页机制让虚拟内存使用不受物理内存大小严格限制?

换页机制可以把暂时不用的页内容写入磁盘 Swap 区,从而释放物理页给当前更需要的虚拟页使用。因此,多个进程拥有的虚拟内存总量可以超过物理内存容量。

但这不表示所有虚拟页能同时驻留在物理内存中。任意时刻,CPU 真正能直接访问的仍然是物理内存中的页。如果活跃页总量超过物理内存容量,就可能频繁换页甚至颠簸。

题 2:缺页异常一定说明程序访问了非法地址吗?

不一定。

缺页异常可能是因为访问了非法地址,也可能是访问了合法虚拟页,但该页尚未分配物理页,或者该页内容已经被换出到 Swap 区。

题 3:FIFO 和 LRU 的区别是什么?

FIFO 根据页面进入内存的先后顺序选择牺牲页,最早进入内存的页最先被换出。

LRU 根据最近访问情况选择牺牲页,最近最久没有被访问的页被换出。

题 4:Second Chance 为什么比 FIFO 更合理?

Second Chance 在 FIFO 队列基础上增加访问位。如果队头页最近被访问过,就清除访问位并移到队尾,暂时不换出它;如果队头页没有最近访问标记,才换出它。

因此,Second Chance 比 FIFO 更能避免换出最近仍然活跃的页。

题 5:为什么 MIN 策略理论最优,但实际不可实现?

MIN 需要知道未来访问序列,才能选择未来最晚再访问或不再访问的页换出。但现实系统通常无法提前知道程序未来会访问哪些页,所以 MIN 只能作为理论最优基准。

题 6:颠簸发生时,为什么 CPU 利用率或有效吞吐会变差?

颠簸时,进程频繁缺页,大量时间消耗在缺页异常处理、等待磁盘 I/O、换入换出和调度切换上。程序真正执行的时间变少,因此系统有效吞吐显著下降。

CPU 可能因为等待 I/O 而空闲,也可能忙于内核态换页处理;但无论哪种情况,用户程序推进效率都会很差。

题 7:工作集模型中的 [t - x, t] 是什么意思?

[t - x, t] 表示从过去的 t - x 时刻到当前 t 时刻的时间窗口。

在这个窗口内被访问过的页组成当前工作集。

题 8:如果一个页很久没有被访问,工作集模型会如何处理它?

如果一个页超过时间窗口 x 都没有被访问,它就不再属于当前工作集。

这意味着它可以成为换出候选页,但不代表系统一定会立刻换出它。


❗ 本节核心结论: 自测题的关键修正是:不要把 Swap 理解成物理内存,不要把 Page Fault 等同于非法访问,也不要把“不属于工作集”理解成“必定立即换出”。

22. 复习清单

学完《物理内存管理 II》后,应能回答以下问题:

  1. 物理内存和磁盘分别是什么?
  2. Swap 区的作用是什么?
  3. 为什么说 Swap 不是把磁盘变成物理内存?
  4. 为什么虚拟内存总量可以超过物理内存容量?
  5. 缺页异常有哪些可能原因?
  6. Page Fault 和 Segmentation Fault 有什么区别?
  7. 换出一个页时,页表项会发生什么变化?
  8. 换入一个页时,为什么可能使用不同的物理页?
  9. 换入位置改变后,如何更新虚拟页到物理页的映射?
  10. 为什么修改页表后要考虑 TLB?
  11. 按需分配有什么好处和代价?
  12. 页替换策略解决什么问题?
  13. MIN 为什么理论最优?
  14. MIN 为什么现实中难以实现?
  15. FIFO 的规则是什么?
  16. FIFO 有什么缺点?
  17. Second Chance 如何改进 FIFO?
  18. LRU 的规则是什么?
  19. LRU 为什么符合局部性原理?
  20. MRU 在什么情况下可能有意义?
  21. 什么是颠簸?
  22. 为什么颠簸会导致系统有效吞吐下降?
  23. 好的页替换策略能否彻底消除颠簸?
  24. 工作集模型中的 [t - x, t] 是什么意思?
  25. 工作集模型和 LRU 有什么区别?
  26. 工作集模型相比 LRU 的优势是什么?
  27. 一个页不属于工作集是否意味着它一定马上被换出?

结论

《物理内存管理 II》的核心,是理解物理内存不足时操作系统如何维持系统运行。

这一讲可以压缩为一句话:

当物理内存不足时,操作系统可以把暂时不用的页内容换出到磁盘 Swap 区;再次访问时通过缺页异常换入,并更新页表映射;内存满时,页替换策略决定换出哪个页;如果活跃页需求超过物理内存容量,就可能发生颠簸;工作集模型用于估计进程当前真正需要的页集合,从而帮助系统减少频繁换页。

真正掌握这一讲,需要形成四个直觉:

  1. Swap 不是内存,只是临时存放页内容的外存区域。
  2. 虚拟地址可以保持不变,但背后的物理页可以换出、换入、改变位置。
  3. 页替换策略是在估计“哪个页未来最不重要”。
  4. 工作集模型比单个替换策略更高一层,它关心进程当前需要多少活跃页。

因此,物理内存管理 II 不是简单地“内存不够就放磁盘”。它是一套围绕缺页异常、页表更新、替换策略、局部性和工作集控制构成的动态管理机制。