Appearance
题目
系统为某进程分配了 4 个页框,该进程已访问的页号序列为 2, 0, 2, 9, 3, 4, 2, 8, 2, 4, 8, 4, 5。若进程要访问的下一页的页号为 7,依据 LRU 算法,应淘汰页的页号是( )。
错因
B
可能没把整个序列走完一遍,停在某个中间状态——比如以为最早进来的就是 LRU,看到 3 是序列里早期出现的,就当成最久未用。但 LRU 是最近最久未用,不是"最早进来",要看的是每个页最后一次被访问的时间,不是首次进入时间。
C
把"高频访问"误以为是"最近未用"——序列里 4 出现了 3 次(位置 6、10、12),看似常驻;但题问的是淘汰,正是要找最近最久没碰的那个,4 是最后访问的反而不该淘汰。把"出现多次"当成淘汰对象正好选反了。
D
可能只看了序列后半段,发现 8 出现位置在 8 和 11——比 5 早,就以为它是最久未用。但实际上 4 在 8 之后还出现过两次(位置 10、12),5 在最末尾(位置 13),整个内存里"最近最久未访问"的页要从最后一次出现位置往前数最远的那个,是 2,不是 8。
总解析
LRU 算法核心:维护一个按"最近访问时间"排序的栈结构——访问到一页就把它移到栈顶,淘汰时把栈底(最久未访问)扔掉。
逐次走查序列 2, 0, 2, 9, 3, 4, 2, 8, 2, 4, 8, 4, 5(4 个页框):
| 步 | 访问 | 命中? | 操作 | 栈状态(左=底=LRU,右=顶=MRU) |
|---|---|---|---|---|
| 1 | 2 | 缺 | 装入 | [2] |
| 2 | 0 | 缺 | 装入 | [2, 0] |
| 3 | 2 | 命中 | 提顶 | [0, 2] |
| 4 | 9 | 缺 | 装入 | [0, 2, 9] |
| 5 | 3 | 缺 | 装入 | [0, 2, 9, 3] |
| 6 | 4 | 缺 | 满,淘汰栈底 0 | [2, 9, 3, 4] |
| 7 | 2 | 命中 | 提顶 | [9, 3, 4, 2] |
| 8 | 8 | 缺 | 满,淘汰栈底 9 | [3, 4, 2, 8] |
| 9 | 2 | 命中 | 提顶 | [3, 4, 8, 2] |
| 10 | 4 | 命中 | 提顶 | [3, 8, 2, 4] |
| 11 | 8 | 命中 | 提顶 | [3, 2, 4, 8] |
| 12 | 4 | 命中 | 提顶 | [3, 2, 8, 4] |
| 13 | 5 | 缺 | 满,淘汰栈底 3 | [2, 8, 4, 5] |
当前内存状态:[2, 8, 4, 5](从栈底到栈顶 = 从 LRU 到 MRU)
下一次访问页号 7(不在内存)→ 满了,要淘汰栈底——也就是 2。
验证:序列里 2 最后一次访问在第 9 步,之后再也没出现过;剩下三页(4 在第 12、8 在第 11、5 在第 13)都比 2 更新。"最久未用"确实是 2。
最终答案是 A。