Skip to content

分页与虚存:大半数题都是同一条链走一遍(专题总纲)

Intro

虚存这一章的名词密度是全书最高的:页目录、页表、页表项、页框、TLB、PDBR、驻留集、工作集、抖动……翻起来像十几个知识点。

但拆开看,多数题干的是同一件事:给你一个虚地址,让你顺着一条链走到底。 先把这条链吃透,剩下两类——链断掉之后的缺页与置换、链两侧的系统行为——都建在它上面。

一条链,从头走到尾

虚地址 → 切成「页号 + 页内偏移」→ 拿页号去表里查 → 读出页框号 → 拼回物理地址

而中间「查表」那一步,永远是同一个乘加

表项地址 = 表的起址 + 编号 × 表项宽度

二级页表就是把这个乘加做两遍

  1. 页目录项地址 = PDBR + 页目录号 × 4 → 读出来得到页表的基址
  2. 页表项地址 = 页表基址 + 页号 × 4 → 读出来得到页框号
  3. 物理地址 = 页框号 左移偏移位数 + 页内偏移

整个专题就是这三行的反复。三级、四级页表同理,多做几遍而已。

必错点一:算出来的是「表项在哪」,不是页框号

这两样在真题里是分开给分的——表项地址一档、从那个地址读出来的页框号另一档。很多人把表项地址直接当页框号往下拼,一步错到底。

写的时候在每一步旁边标一个字:这一步得到的是地址,还是地址里的内容

必错点二:PDBR 里存的是物理地址

如果 PDBR 存虚地址,MMU 为了找到页目录就得先查一次页表——而查页表又得先找到页目录。死循环。所以它只能存物理地址。

还有一个高频问法:PDBR 跟着「地址空间」走,不跟着「执行流」走。 进程切换换地址空间,PDBR 要变;线程切换共享同一个地址空间,PDBR 不变。

一个反复出现的小技巧:高位相同就是同一个东西

  • 两个虚地址高 20 位相同 → 落在同一页(4 KB 页);
  • 高 10 位相同 → 归同一个二级页表管(同一个 4 MB 块)。

真题里「某函数占几页」「这两个地址访问的是不是同一张页表」这类问法,全靠比高位,不用真去查表。

与组成原理那一半合起来看

CO 也有一整类 Cache 与虚存的大题。两边看的是同一个地址、同一张图,只是问法不同:

问什么
组成原理这个地址切开之后,各段是多少位;查 Cache 命不命中
操作系统拿这些位去表里走一遍,最后落在哪个物理地址;表里没有该怎么办

所以这两个专题建议连着做——CO 那边的总纲在这里,位段怎么切讲得更细;这边接着讲切完之后怎么用。

链走不下去:缺页与置换

页表项的有效位是 0,链在这里断了。接下来只有三件事。

一、时间怎么算——探测的开销要付两次

缺页不是「在正常时间上加一个缺页处理时间」。 完整的账是:

探测(查 TLB + 查页表,发现有效位为 0)
  + 缺页处理(把页调进来,这一段是毫秒级,比前后都大好几个数量级)
  + 重新执行(再查一遍 TLB、再访问一次主存)

前面那段探测的开销付了两次。这三段是绑在一起判的——2009 年那道题里,任何一段漏算,这一档 2 分直接归零,不是扣一点。

对比一下另外两条路径会更清楚:TLB 命中就只有 TLB + 访存两段(命中时根本不查页表,这正是 TLB 的价值);TLB 未命中但页表有效,是 TLB + 页表 + 访存三段。

二、换谁出去——三个算法看三样不同的东西

算法看什么
FIFO装入时刻最早的(跟最近有没有被访问无关)
LRU最近访问时刻最久远的
CLOCK使用位,扫到 0 就换,扫到 1 就清零后往前走

规则不能串。CLOCK 还有个专属的坑:所有页框的使用位都是 1 时,要扫满一圈把它们全部清零,再绕回起点换掉起点那一个。

改进型 CLOCK 要两个字段——访问位 A 和修改位 M,优先换干净页,省掉一次写回。

三、题面自定义的策略,照着题面走

真题考过一种自定义回收策略:定期把没被访问的页框回收到空闲链,但内容不清空。于是缺页时如果那一页还在链里,直接放回来,零磁盘 I/O。

这类题不要往教科书算法上套,把题面的规则当成新算法逐条执行就行。

一次走链的答卷长什么样

二级页表、页 4 KB、页表项 4 B、PDBR = 00300000H,求虚地址 12345678H 的物理地址。卷面上写这几行:

切位(10 / 10 / 12):
    页目录号 = 12345678H >> 22        = 048H
    页    号 = (12345678H >> 12) & 3FFH = 345H
    页内偏移 = 12345678H & FFFH        = 678H

① 页目录项地址 = PDBR + 页目录号×4 = 00300000H + 048H×4 = 00300120H
   ↑ 这是「表项在哪」   读出其中内容 → 页表所在的页框号,设为 00A05H
                        页表基址 = 00A05H << 12 = 00A05000H   ← 别漏这次左移
② 页表项地址   = 00A05000H + 345H×4 = 00A05D14H
   ↑ 仍是「表项在哪」   读出其中内容 → 目标页的页框号,设为 002EAH
③ 物理地址     = 002EAH << 12 | 678H = 002EA678H

每一步右边那句「这是表项在哪 / 读出来才是内容」就是这类题的全部要害——①② 算出的都是地址,还要再读一次;只有 ③ 才是答案。真题里这两样是分开给分的。

还要留意:表项里存的是页框号,不是基址。 拿到页框号必须左移一次(页内偏移位数)才变成地址—— 这一步真题专门设过问(「若该目录项中存放的页框号为 00301H,则页表项的物理地址是多少」)。

下笔前先写三个数

  1. 先写下三个数:页多大、虚地址多少位、页表项多宽。切法和乘加只由它们决定。
  2. 顺着链一步一步写,每一步标清得到的是地址还是内容。
  3. 遇到有效位为 0 才进置换分支,先认准题面用的是哪个算法,再画帧表逐次模拟。

真题的两种形态

第一组 · 顺着链走一遍——给虚地址算物理地址、算页表项地址、判两个地址是否同页或同表、算页表本身要占多少空间。这一组是地基。

第二组 · 表里没有——缺页的时间怎么累加、按某个算法该换哪一页、自定义回收策略下会发生什么。

交卷前扫一眼

先写页多大·地址多少位·表项多宽 · 每步标清得到的是「地址」还是「内容」 · 页框号要左移一次 · 缺页按「探测+处理+重执行」三段算

配套内容

逐题精讲(建设中)——真题作答与 AI 判分入口见站内大题专题

基础没打牢的,先回这几篇:

考纲要求、但这 9 道真题没有正面考过的(专题的巩固栏里配了题,可以直接练):

  • 基本分段段页式管理——段长可变、要做越界检查,别当成「另一种页」
  • 虚拟内存性能——工作集、抖动的判定,以及 FIFO 的 Belady 异常 (页框分配考过:2010 年那道题的题面就是「固定分配局部置换、分 4 个页框」,2012 年整题都在推演页框的回收与再分配。)

真题练习