操作系统 07|页面置换:OPT / FIFO / LRU 手算一遍,再讲清 Belady 和改进型 Clock

2019 年第 29 题:LRU 算法、局部置换、预分配 4 个页框,访问序列 0,1,2,7,0,5,3,5,0,2,7,6,问产生页置换的总次数。

我数出来缺页 9 次,可选项最大只有 6。我以为自己数错了,连数三遍都还是 9。

最后才反应过来:这题问的是置换次数 ,不是缺页次数。

前 4 次缺页是在填空白页框 ,根本没有"换出"这个动作,不算置换。9 − 4 = 5 → 答案 C。

这两个数字一定要分清:缺页次数 9,置换次数 5。凡是题目问"置换",就要扣掉开头那些把空页框填满的次数。


〇、先花两分钟:页面置换到底在换什么

先扫盲三个词:

  • 缺页(Page Fault) :要访问的页面不在内存 里,触发一次缺页中断。只要没命中,就是缺页。

  • 置换(Replacement) :内存满了 还得往里放新页,就必须挑一个旧的踢出去。这个"挑一个踢出去"的动作才叫置换。

  • 命中 :要访问的页面就在内存里,什么都不用做。

所以三者的关系是:

复制代码
缺页次数 = 置换次数 + 开头把空页框填满的次数

判断口诀 :内存还没装满 时的缺页 → 只是"装入",不叫置换 ;内存满了之后 的缺页 → 必须"换出旧页",才叫置换。

什么时候需要置换? 请求分页系统里,进程只把一部分页面装进内存。访问时发现页不在内存(缺页),OS 就把它从外存调进来;如果此时分配给该进程的页框已经用完 ,就得先选一页换出去------选哪一页,就是页面置换算法要解决的问题。


一、四种算法,一个序列,逐个手算

下面用同一个序列 把三种经典算法走一遍(Clock 单独讲)。假设系统给进程分配 3 个页框,访问序列是:

复制代码
2, 3, 2, 1, 5, 2, 4, 5, 3, 2, 5, 2

① 最佳置换算法 OPT(理想算法,实现不了)

规则 :淘汰未来最长时间不再被访问的页面(或者干脆以后都不用了的)。

它为什么"最佳" :它是开了天眼 的算法------必须预先知道后面的访问序列,实际系统做不到。它的价值是作为一个理论下限,用来评价其他算法有多差。

手算过程(内存状态按「最久未用 → 最近使用」写):

访问 2 3 2 1 5 2 4 5 3 2 5 2
内存 2 2,3 命中 2,3,1 2,3,5 命中 2,5,4 命中 2,5,3 命中 命中 命中
缺 缺 缺 换 1 换 3 换 4

→ 缺页 6 次,置换 3 次

② 先进先出 FIFO(最容易实现,也最容易出问题)

规则 :淘汰最早进入内存的那一页。就像排队,先来的先走。

访问 2 3 2 1 5 2 4 5 3 2 5 2
内存 2 2,3 命中 2,3,1 3,1,5 1,5,2 5,2,4 命中 2,4,3 命中 4,3,5 3,5,2
缺 缺 缺 换 2 换 3 换 1 换 5 换 2 换 4

→ 缺页 9 次,置换 6 次

注意第 5 步访问 2:2 明明刚被访问过 (第 3 步),但 FIFO 不管这个,它只看"谁先来的",照样把它换走了。这就是 FIFO 不符合程序局部性原理的地方,也是它容易产生 Belady 异常的根源。

③ 最近最久未使用 LRU(考得最多,性能最好)

规则 :淘汰最近最久没被用过 的那一页。它相信:最近用过的,待会儿大概率还会用(局部性原理)。

访问 2 3 2 1 5 2 4 5 3 2 5 2
内存 2 2,3 命中 2,3,1 2,1,5 命中 5,2,4 命中 4,5,3 5,3,2 命中 命中
缺 缺 缺 换 3 换 1 换 2 换 4

→ 缺页 7 次,置换 4 次

三种算法摆在一起看

算法 缺页次数 置换次数 特点
OPT 6 3 理论最优,实现不了,只作参照
LRU 7 4 性能好,需要硬件支持(寄存器/栈),开销大
FIFO 9 6 实现最简单,性能最差,可能 Belady 异常

三者的比较关系:OPT ≤ LRU ≤ FIFO(缺页次数)。记住这个不等式,选择题直接排除。

2019(29) 那道题(4 个页框、LRU、序列 0,1,2,7,0,5,3,5,0,2,7,6)完整推演:

复制代码
访问 0(缺) 1(缺) 2(缺) 7(缺) → 内存满:0,1,2,7   ← 前 4 次只是装入,不算置换
访问 0 命中 → 1,2,7,0
访问 5 缺 → 淘汰 1 → 2,7,0,5     ← 置换 1
访问 3 缺 → 淘汰 2 → 7,0,5,3     ← 置换 2
访问 5 命中 → 7,0,3,5
访问 0 命中 → 7,3,5,0
访问 2 缺 → 淘汰 7 → 3,5,0,2     ← 置换 3
访问 7 缺 → 淘汰 3 → 5,0,2,7     ← 置换 4
访问 6 缺 → 淘汰 5 → 0,2,7,6     ← 置换 5

缺页 9 次,置换 5 次 → 答案 C


二、LRU 的秒杀技巧:从后往前数

2015(27) 是道"看起来要画半天表,其实十秒能出答案"的题:

4 个页框,已访问序列 2,0,2,9,3,4,2,8,2,4,8,4,5,若下一页访问 7,依据 LRU 应淘汰哪一页?

不要从头模拟。 直接从序列末尾往前数 ,数出 k 个(k = 页框数)不同的页号:

复制代码
序列尾部:... 2, 4, 8, 4, 5
从后往前:5(第1个) → 4(第2个) → 8(第3个) → 2(第4个)  ← 数够 4 个,停

数出的这 4 个就是此刻内存里的 4 个页 ,而其中最早数到的那个(2)就是最久没被碰过的 → 淘汰 页 2,答案 A。

原理:不管过去发生了什么,此刻内存里一定装着"最近出现过的 k 个不同页"。所以从后往前数 k 个不同页号,直接就还原了内存快照。

2025(26) 也可以用这个思路验证:3 个页框、初始已装入 0,1,2,序列 0,1,2,0,5,1,4,3,0,2,3,2,0,逐步模拟下来缺页 6 次 → 答案 B。


三、Belady 异常:页框越多,缺页反而越多

Belady 异常 :分配给进程的页框数增加 ,缺页次数不降反升。这是反直觉的,但确实会发生。

2014(30) 直接考它:可能出现 Belady 异常的是?

  • Ⅰ. LRU → ❌(LRU 是栈式算法,不会发生)

  • Ⅱ. FIFO → ✅

  • Ⅲ. OPT → ❌

→ 答案 A:仅 Ⅱ

看一个真实算例

用经典序列 1,2,3,4,1,2,5,1,2,3,4,5:

页框数 FIFO 缺页次数
3 个 9 次
4 个 10 次 ← 页框变多,缺页反而多了一次

原因就是前面说的:FIFO 只看"谁先来",完全不管页面最近有没有被用过,于是可能把"马上又要访问"的页换出去,而多出来的那个页框反而改变了淘汰顺序,把情况搞得更糟。

一句话记忆 :只有 FIFO 会 Belady。LRU 和 OPT 都是"栈式算法"------页框越多,内存里装的页只会越多,缺页次数必然单调不增。


四、改进型 Clock:用两个位把页分成四类

Clock(时钟)算法 :给每页一个访问位 A ,页面排成一个环形队列。淘汰时像时钟指针一样扫,遇到 A=0 的就淘汰;遇到 A=1 就把它置 0 再跳过(给它第二次机会)。

改进型 Clock 再加一个修改位 M,一共四类(A = 访问位,M = 修改位):

2016(26) 就考淘汰次序:

类别 含义 淘汰优先级
(0, 0) 最近没访问过,也没修改过 第 1 优先淘汰(最省事,直接扔)
(0, 1) 最近没访问过,但改过 第 2(要写回磁盘,代价大一点)
(1, 0) 最近访问过,没改过 第 3(刚用过,可能还要用)
(1, 1) 最近访问过,也改过 最后才考虑(又要用、又要写回)

→ 淘汰次序 (0,0) → (0,1) → (1,0) → (1,1) ,答案 A

记忆法 :先看 A (没访问过的先走),A 相同再看 M(没改过的先走,省一次写回)。

2021(28) 把改进型 Clock 和地址变换揉在一起考:虚拟地址 02A01H、页大小 4KB、2 个固定页框。

解题分三步:

复制代码
① 页大小 4KB = 2^12 B → 低 12 位是页内偏移
   02A01H = 0000 0010 1010 0000 0001
   低 12 位 = A01H(页内偏移,变换前后不变)
   页号 = 02H
​
② 查页表发现 2 号页「存在位 = 0」,不在内存 → 缺页,需要置换
   按改进型 Clock 从已在内存的两页里挑一页淘汰(挑中 3 号页,它占着 60H 页框)
​
③ 2 号页装进 60H 页框
   物理地址 = 60H 拼上偏移 A01H = 60A01H

→ 答案 C:60A01H

这题的关键是页内偏移不变 :页框号从 60H 来,偏移 A01H 原样搬过去,拼起来就行。


五、工作集与抖动:内存"不够用"的两种表现

工作集(2016(29))

工作集 :在时刻 t,进程最近 k 次内存访问 所访问过的页面集合(k 叫窗口大小),记作 w(k, t)。

2016(29) :窗口大小 6,序列 ..., 1,3,4,5,6,0,3,2,3,2,0,4,0,3,2,9,2,1, ...,t 时刻工作集?

取 t 时刻之前最近 6 次 访问:6, 0, 3, 2, 3, 2,去重 → {6, 0, 3, 2} → 答案 A

(注意 B 选项 {2,3,0,4} 是再往前 6 次的结果,不是"最近"的。)

抖动 / 颠簸(Thrashing)

抖动 :刚换出去的页面马上又要访问 ,于是又换别的页出去,而那个页又很快被访问......系统大部分时间都花在换页上,CPU 利用率暴跌。

根因 :分配给进程的页框数少于它当前的工作集大小。

2011(29) 问有效对策:

  • Ⅰ. 撤销部分进程 → ✅(减少并发进程数,把页框还给留下来的进程)

  • Ⅱ. 增加磁盘交换区容量 → ❌(抖动的主因不是外存不够)

  • Ⅲ. 提高用户进程优先级 → ❌(换页频率不会因为优先级而降低)

→ 答案 A:仅 Ⅰ

2022(30) 反过来问"不会影响缺页率的是":

  • A. 页面置换算法 → 会(LRU 通常低于 FIFO)

  • B. 工作集大小 → 会(工作集越大,给的页框不够就越容易缺页)

  • C. 进程数量 → 会(进程越多,每进程分到的页框越少)

  • D. 页缓冲队列长度 → 不会 (它影响的是置换的速度 ,不是缺页的次数)

→ 答案 D

2020(28) 考有效访存时间由什么决定 → 四个全要 :缺页率、磁盘读写时间、内存访问时间、执行缺页处理程序的 CPU 时间 → 答案 D。


六、易错点清单

  1. 把缺页次数当置换次数 → 问"置换"要扣掉开头填满空页框的次数(2019(29):9 缺页 = 5 置换)

  2. 从头模拟 LRU → 用"从后往前数 k 个不同页号"秒出内存快照(2015(27))

  3. 认为所有算法都会 Belady → 只有 FIFO(2014(30))

  4. 改进型 Clock 先比 M 再比 A → 反了,先看 A 再看 M(2016(26))

  5. 抖动时想到扩交换区 / 提优先级 → 都无效,撤销部分进程才是正解(2011(29))

  6. 工作集取"往前"而不是"最近" → 必须从 t 时刻往回取 k 次(2016(29))

  7. 认为 LRU 一定最优 → LRU 只是接近 OPT,理论上 OPT 才是下限

  8. 页缓冲队列影响缺页率 → 不影响,只影响置换速度(2022(30))

  9. 忘记页内偏移不变 → 地址变换只换页号部分,偏移原样拼接(2021(28))

  10. 以为页置换是系统调用 → 不是,它完全由 OS 内部完成(2021(32) 答案 C 是"创建新进程")


速查表(文末收藏版)

三种算法对比

算法 规则 缺页 Belady 备注
OPT 淘汰未来最久不用的 最少 不会 理论下限,实现不了
LRU 淘汰最近最久未用的 次少 不会 需硬件支持,开销大
FIFO 淘汰最早进来的 最多 会 实现最简单
Clock 环形扫描访问位 接近 LRU --- 开销小,实际系统常用

LRU 秒杀法

复制代码
从序列末尾往前数,数出 k 个(k = 页框数)不同的页号
= 此刻内存快照;其中最早数到的那个 = 要淘汰的页

改进型 Clock 四类淘汰次序

复制代码
(0,0) → (0,1) → (1,0) → (1,1)        先看访问位 A,再看修改位 M

关键数字关系

复制代码
缺页次数 = 置换次数 + 开头填满空页框的次数
OPT ≤ LRU ≤ FIFO(缺页次数)
只有 FIFO 会出现 Belady 异常

抖动与工作集

复制代码
抖动成因:分配的页框数 < 当前工作集大小
抖动对策:撤销部分进程(扩交换区、提优先级都无效)
工作集:t 时刻往前取 k 次访问,去重后的页面集合
不影响缺页率:页缓冲队列长度

本文依据 :王道《操作系统考研复习指导》虚拟内存管理章节;真题题干、选项与答案均逐条核对 zhenti_all.json(2009--2025 共 799 题,操作系统部分 170 题),涉及 2011(29)、2014(30)、2015(27)(30)、2016(26)(29)、2019(29)、2020(28)、2021(28)(32)、2022(29)(30)、2025(26)(27)。文中三种算法的对比演算(序列 2,3,2,1,5,2,4,5,3,2,5,2)与 Belady 算例(序列 1,2,3,4,1,2,5,1,2,3,4,5)均为本文自行推演,与算法定义一致。

相关推荐
硅基手札16 小时前
操作系统设计思想系列 05 · RTOS 核心矛盾 — 资源受限 × 时间确定性的设计决策树
linux·mcu·架构·操作系统·嵌入式开发·rtos·设计思想
云计算练习生1 天前
什么是文件权限?Linux 中 rwx 与数字权限的对应关系
linux·运维·服务器·操作系统·文件权限管理
小oo呆1 天前
【学习心得】Python多进程
python·操作系统
硅基手札2 天前
操作系统设计思想系列 06 · FreeRTOS 深度 — 极简可移植范本
架构·操作系统·freertos·实时操作系统·嵌入式开发·设计思想
m0_547486662 天前
《计算机操作系统》全套PPT课件(武汉大学)
操作系统·计算机操作系统
意法半导体STM323 天前
【官方原创】LAT6041 STM32MP1x USB OTG FIFO设置
stm32·单片机·嵌入式硬件·mcu·fifo·stm32mp1x
2CM_Embed4 天前
μC/OS-II 内核结构零基础详解(二):任务控制块、就绪表、调度器与中断切换
操作系统
MicrosoftCloud4 天前
操作系统 02|进程到底被谁推着走?
操作系统·线程·进程·pcb·408·进程状态·调度
坐看风云变幻4 天前
《系统架构师成长之路》第 2 期|计算机基础:从一次 malloc 看懂内存管理
操作系统