Appearance
分页与虚存:大半数题都是同一条链走一遍(专题总纲)
Intro
虚存这一章的名词密度是全书最高的:页目录、页表、页表项、页框、TLB、PDBR、驻留集、工作集、抖动……翻起来像十几个知识点。
但拆开看,多数题干的是同一件事:给你一个虚地址,让你顺着一条链走到底。 先把这条链吃透,剩下两类——链断掉之后的缺页与置换、链两侧的系统行为——都建在它上面。
一条链,从头走到尾
虚地址 → 切成「页号 + 页内偏移」→ 拿页号去表里查 → 读出页框号 → 拼回物理地址而中间「查表」那一步,永远是同一个乘加:
表项地址 = 表的起址 + 编号 × 表项宽度
二级页表就是把这个乘加做两遍:
- 页目录项地址 = PDBR + 页目录号 × 4 → 读出来得到页表的基址
- 页表项地址 = 页表基址 + 页号 × 4 → 读出来得到页框号
- 物理地址 = 页框号 左移偏移位数 + 页内偏移
整个专题就是这三行的反复。三级、四级页表同理,多做几遍而已。
必错点一:算出来的是「表项在哪」,不是页框号
这两样在真题里是分开给分的——表项地址一档、从那个地址读出来的页框号另一档。很多人把表项地址直接当页框号往下拼,一步错到底。
写的时候在每一步旁边标一个字:这一步得到的是地址,还是地址里的内容。
必错点二: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,则页表项的物理地址是多少」)。
下笔前先写三个数
- 先写下三个数:页多大、虚地址多少位、页表项多宽。切法和乘加只由它们决定。
- 顺着链一步一步写,每一步标清得到的是地址还是内容。
- 遇到有效位为 0 才进置换分支,先认准题面用的是哪个算法,再画帧表逐次模拟。
真题的两种形态
第一组 · 顺着链走一遍——给虚地址算物理地址、算页表项地址、判两个地址是否同页或同表、算页表本身要占多少空间。这一组是地基。
第二组 · 表里没有——缺页的时间怎么累加、按某个算法该换哪一页、自定义回收策略下会发生什么。
交卷前扫一眼
先写页多大·地址多少位·表项多宽 · 每步标清得到的是「地址」还是「内容」 · 页框号要左移一次 · 缺页按「探测+处理+重执行」三段算
配套内容
逐题精讲(建设中)——真题作答与 AI 判分入口见站内大题专题。
基础没打牢的,先回这几篇:
考纲要求、但这 9 道真题没有正面考过的(专题的巩固栏里配了题,可以直接练):
- 基本分段|段页式管理——段长可变、要做越界检查,别当成「另一种页」
- 虚拟内存性能——工作集、抖动的判定,以及 FIFO 的 Belady 异常 (页框分配考过:2010 年那道题的题面就是「固定分配局部置换、分 4 个页框」,2012 年整题都在推演页框的回收与再分配。)