考研OR工作,这是个老话题了。但不管你走哪条路,操作系统这一关都得过,而「虚拟存储器」这一章,往往是很多人复习时最容易卡住的地方。我见过不少同学,提起虚拟内存就一句话:「内存不够,拿硬盘凑嘛。」真要这么简单就好了。去面试被追问一句「缺页中断之后整个进程还能不能继续执行?」、「LRU为什么在工程里很少直接实现?」,或者考研卷子上出一道「请求分页和基本分页的区别」的简答题,直接就露馅。
这篇文章,就是给在「考研」和「工作」这两条路上反复纠结的同学,把虚拟存储器这章的简答题考点和疑难知识点一次性捋清楚。不堆概念,也不念课本,用面试和考场上真正会问、会考的方式来讲。适合正在复习操作系统准备考研初试的人,也适合准备计算机基础面试的人,甚至单纯想把这块知识补扎实的同学,都可以放心看下去。
1. 虚拟存储器的本质:为什么说「内存不够硬盘凑」不算全对
1.1 局部性原理:所有调页机制的地基
很多人上来就背「虚拟存储器是基于局部性原理的」,但真要问什么叫局部性,就只说得出字面意思。这里我打个比方:你去图书馆复习,不会把整书架的书全抱到桌上,只会拿最近几章要用的;而且你刚翻过的重点内容,往往会反复看。程序在运行的时候也是这个德行——某个时间段内,访问的指令和数据的页就那么几个。
这背后就是两个局部性:时间局部性和空间局部性。时间局部性说的是刚访问过的内容过一会儿大概率还会访问,典型场景是循环、反复调用的函数;空间局部性说的是访问了一个地址后,旁边的地址往往也被访问,典型场景是数组遍历、顺序执行的指令。这两条看着简单,其实是整个虚拟存储器设计的地基。没有局部性,按需调页就会退化成「每次访问都缺页」,虚拟内存就废了。
这个原理在答题时有个很实用的姿势:当你被问到「为什么虚拟存储可行」的时候,不要只写「因为有局部性原理」,要补一句——「局部性原理使得程序执行时只需要装入少部分页面即可运行,而暂时不用的页面可以留在外存,系统才有机会以较小的内存运行大作业。」这样答,得分点才踩得全。
1.2 虚拟地址空间与物理地址空间:一张图看懂双映射
第二个高频基础考点是地址空间。32位系统下,每个进程的虚拟地址空间是4GB,这是一个逻辑上的、连续的空间。但物理内存可能只有2GB,甚至更少。程序看到的是4GB连续空间,实际这一页到底放在物理内存哪一帧,还是压根不在内存里,都由内存管理单元配合页表去解决。
这里有个大家容易忽略的点:程序从头到尾访问的都是「逻辑地址」,CPU发出的也是逻辑地址,真正去物理内存里取数据,是地址变换完成后才发生的事。所以虚拟存储器的核心工作,就是维护从虚拟页号到物理帧号的映射关系,并处理「这个页不在内存」的情况。
我建议复习的时候自己动手画一张草图:左边虚拟页号序列,右边物理帧号序列,中间是页表。标出哪些页在内存、哪些页在外存,以及快表(TLB)在哪个环节介入。这张图画懂了,后面理解请求分页、缺页中断、页面置换就顺了。
1.3 虚拟存储器的三大特征:离散性、多次性、对换性
这三大特征是简答题的标准答案,但你得真明白每个词在说什么,不然换个问法就懵了。
离散性,是最容易被忽视的。虚拟存储器要求程序可以按页或按段离散存放在内存中,不要求全部装入连续空间。这是虚拟存储器能够实现的前提——正因为可以离散存放,我们才能「只装入部分页面」。如果程序必须连续装入,那就算只装一部分也得找一块足够大的连续区域,这就又退回连续分配的坑里了。所以很多教材把「离散性」称为虚拟存储器最重要的特征,是有道理的。
多次性,指一个作业不是一次性全部装入内存,而是分成多次调入。这正是「虚拟」二字的体现——传统存储管理要求作业全部装入才能运行,这是所谓的「一次性」,现在被打破了。
对换性,指运行中可以让作业换入换出。暂时不用的页面换到外存,需要时再换入。这意味着进程在内存和外存之间是可以来回搬动的,不必把自己「焊死」在某块内存里。
这三个特征要能背,更要能解释。考试问的是「为什么虚拟存储器能实现」,你就用这三条答;问的是「具备哪些特征」,就把三条名字先亮出来,再各补两句展开。注意离散性是结合请求分页和请求分段一起考的,只要抓住「离散存放 + 多次调入 + 允许换出」,这题稳了。
2. 请求分页机制:缺页中断处理的全过程拆解
2.1 请求分页与基本分页的区别:一个「懒加载」的思路
基本分页管理下,作业的所有页必须一次性全部装入内存。请求分页则更像一个「懒加载」的思路:先把作业的目录建好,程序跑起来时访问到哪一页,发现不在内存,才把这一页从磁盘调入。
区别的考点通常写成「请求分页是在基本分页基础上增加了请求调页功能和页面置换功能」。这句话每个字都值得拆:多了「请求调页」意味着可以按需调入;多了「页面置换」意味着内存不够时要腾地方。基本分页没有这两个功能,所以作业要么全装进来,要么就别想运行。这俩功能也是本章后续内容的引子——缺页中断处理就是请求调页的具体实现,页面置换算法则是另一条线。
答这道题的时候,别只写「请求分页可以只调入部分页面」,要把落脚点放在「基于局部性原理,程序运行时只需部分页面在内存即可」上。另外要提一句页表结构的变化:请求分页的页表项除了页号和帧号的对应关系,还加入了状态位、修改位、访问字段、外存地址,这是和基本分页页表最直观的区别。
2.2 缺页中断的处理流程:硬件到软件的接力
这条链路是本章最值得背熟的流程之一,面试官很喜欢连环追问。我拆成步骤逻辑给大家串联一遍,别死记,按「谁发现问题、谁先处理、谁负责换页、谁负责复现场景」这条线理解。
第一步,硬件阶段。CPU在访问某个逻辑地址时,MMU把虚拟页号拿去查页表(通常先查快表)。发现对应的页表项状态位为0,说明这一页不在内存,此时硬件触发一个缺页中断。注意,缺页中断属于内中断的一种,由CPU内部的程序运行状态异常引起。
第二步,操作系统介入。CPU响应中断后,保存当前进程的现场,这点和普通中断一样。然后操作系统转去执行缺页中断处理程序。处理程序先检查这个检查要访问的地址是否合法,不合法就直接报错终止进程;合法,就在内存中找一个空闲物理块。
第三步,如果没有空闲块,查一下有没有「可换出的页」,通常由页面置换算法挑一个倒霉蛋。如果这个倒霉蛋在内存期间被修改过,也就是修改位为1,要先把它写回磁盘,这叫「把脏页刷出去」;没被改过,那它和磁盘上的副本一致,直接覆盖就行,省一次IO。
第四步,把缺的那一页从磁盘调入刚才找出的物理块,更新页表对应项,状态位置1,修改位初始为0,访问字段清零。收回现场,重新执行刚才因缺页中断的指令。
这里面有一个容易被忽略、但特别能体现功底的细节:一条指令执行过程中完全可能触发多次缺页中断。比如一条指令要取指令、取操作数、还可能跨页边界,每个环节访问的页面都可能不在内存。考试的时候如果出这种「一条指令最多发生几次缺页」的选择题,很多人会算错,就是把「一次指令只缺一次页」当成默认前提了。真实情况是,一次访问页面就可能缺一次,跨页再多出一到两次,务必在计算时数清楚。
2.3 页表项里的隐藏字段:状态位、修改位、访问位各管什么
页表项字段这块,简答题很少直接考,但它是理解置换算法和缺页过程的地基。我把四个关键字段串一遍:
- 状态位(存在位):标示该页是否在内存。查页表第一步就看它。为0,则缺页。
- 修改位(脏位):标示该页调入内存后有没有被写过。置换时修改位为1的页,必须写回外存,为0的直接覆盖。这是很多置换算法加入考量的核心字段。
- 访问字段(引用位):记录页面被访问的情况,供置换算法参考。比如头几次访问置个1,Clock算法扫描时碰上0才有资格被换出。
- 外存地址:该页在磁盘上的存放位置。调入的时候靠它去读,缺页时必须有这个地址才能完成调页。
这四项,正好可以串成一道面试题:「如果页表项只有帧号没有状态位,会怎么样?」答案是:系统根本不知道这一页在不在内存,请求分页无从谈起。所以别看这些字段小,每一字节都是为了应对「虚拟」带来的新问题而存在的。
深化一点:修改位对性能的影响非常实际。假如置换时总是优先换出干净页,也就是修改位为0的页,那么换出的开销只有「调入新页」一次IO;如果非要换脏页,就要「写回旧页 + 调入新页」两次IO。这背后就是改进型Clock算法的动机,你们到时候看到就明白了。
3. 页面置换算法:高频考点与实现层面的真实考量
3.1 OPT、FIFO、LRU:三大经典算法的横向对比
页面置换算法是虚拟存储器这章最热闹的考点,没有之一。我用一个引用串把OPT、FIFO、LRU讲透。假设物理块数只有3,访问序列为:1, 2, 3, 4, 1, 2, 5。
FIFO,先进先出,换最早进来的。实现就是个队列,简单粗暴。前三次1、2、3依次装入,第四次访问4时,1最先进来,被踢出去;第五次访问1,2又被踢……最后一统计,缺页次数明显偏多,而且是「先进去的先遭殃」,哪怕你最常用它也没用。
LRU,最近最久未使用,换「最长时间没被碰过」的那个。实现的抽象思路是用访问历史排序,每次访问后重排,淘汰最末尾的。同样的序列,LRU在最后一次访问5时,淘汰的是哪个?是按访问时间倒推最远的那个,缺页次数比FIFO好看不少。
OPT,最优置换算法,淘汰「未来最长时间不再被访问」的页。这玩意是个理论下界——它需要预知未来访问序列,实际系统做不到,但考试计算题里经常用它当参照物,用来证明其他算法和最优解的差距。
三者的对比,我建议直接一张表记心里:
| 算法 | 核心思想 | 是否可实现 | 典型问题 |
|---|---|---|---|
| OPT | 淘汰未来最远才用的页 | 否(理论最优) | 无法预知未来 |
| FIFO | 淘汰最早进入的页 | 是 | 存在Belady异常 |
| LRU | 淘汰最久未访问的页 | 理论上可以,成本高 | 需要维护访问历史 |
顺便说一句,面试被问到「你了解LRU吗」,别一上来就背概念。更好的答法是:先说LRU的理念是「最近的访问倾向延续」,然后立刻补一句「但严格LRU在系统中实现成本较高,通常用Clock近似算法替代」,这一句话就证明了你真的见过工业代码,而不是只在课本上画过图。
3.2 一个被问烂的坑:Belady异常与LRU的栈性质
Belady异常是本小节最经典的坑。简单说,就是FIFO算法下,物理块数从3增加到4,某些访问序列的缺页次数反而变多了——更多的内存,更差的性能,听着反直觉,但确实会发生。
为什么会出现这个诡异现象?因为FIFO只认「谁先来」这个顺序,它换走的页可能是接下来马上就要用、而且在整个进程中会频繁使用的「热页」。本来4个物理块足够把热页装一起,结果FIFO的机械操作反而把热页踢出去了,于是刚换出去又缺页,恶性循环。
更坑的是,一些考生只记得「Belady异常是FIFO的专属」,却不知道背后的理论支撑:LRU和OPT算法都具有栈性质。栈性质的意思是,物理块数增多时,被淘汰的页面集合不会因为内存增大而「恶化」。用大白话讲,LRU和OPT在算法结构上保证了「给你更多的内存,你的留驻桌面只会更好或持平,永远不会更差」。课堂举的经典证明思路是:LRU算法把页面按最近访问时间排序,淘汰的是序列最末端,物理块数增加只是把队列尾部多留几个页面,不会赶走更热门的页。
答题时如果被问到「为什么FIFO有异常而LRU没有」,别再答「LRU更聪明」,要答出「LRU基于访问历史排序,具有栈性质;FIFO只基于进入顺序,不具备这一性质」。把这两个词抛出来,分数就往上走了。
3.3 近似LRU的工业实现:Clock算法及其改进
严格LRU的实现难点在于,每访问一个页面都要维护全局“最近使用顺序”,这在真实系统里开销太大。所以多数操作系统用的是Clock算法,教科书上也叫「最近未使用时钟置换算法」。
Clock算法的精髓是:把物理页想象成围成一圈,一个时钟指针在循环扫描。每个页有个访问位,被访问时置1。换页时,指针走过去检查:
- 访问位为0,说明这页有一段时间没被访问了,换走;
- 访问位为1,说明刚被用过,不清「罪」,但把位改成0,继续看下一页。
这个过程相当于把「很久没访问」的判断,简化成了「上次扫描之后有没有再访问」这样一个折中。最终转一圈,总能把活跃度最低的找到。它的性能接近LRU,但实现代价低得多,所以是工业界的宠儿。
更高阶的分页考点是改进型Clock。它在访问位之外又引入了修改位,把页面分成四类:
- 0类:未访问、未修改,最理想的换出对象,干净且冷门;
- 1类:未访问、但修改过,属于「冷门但是脏」,换出需要写一次磁盘;
- 2类:已访问、未修改,热门但干净;
- 3类:已访问、已修改,又热又脏,换出代价最高。
扫描时第一遍找0类,没有就再扫找1类并顺带把访问位置0,第二轮再找2类、3类。优先级本质是「先赶冷门的,再赶脏不脏」。改进型Clock是不少学校简答题和选择题的压轴常客,理解了分类,就不需要背扫描策略了。
3.4 缺页率计算题模板:从模拟置换表到有效访问时间
虚拟存储器的计算题,万变不离其宗。我给大家一个通用解题框架:
第一,确定引用串。题目会给你一串页面号,比如 1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5。注意有的题目把「刚开始三个物理块是空的」也算缺页,有的不算,读题时看假设。没有特殊说明,我通常按「前几次装入也算缺页」来算,因为每次装入前页都不在内存。
第二,画置换表。列是引用串,行是物理块。一行行模拟,遇到缺页就标记一个F,并在对应块里填入新页号;命中的补个H。这个表画对了,缺页次数不可能算错。
第三,算缺页率=缺页次数/总引用次数。如果题目要求有效访问时间,再用公式:EAT = (1-p)×访问内存时间 + p×(缺页中断处理时间)。其中p就是缺页率。这里要提醒大家,缺页中断处理时间通常远大于内存访问时间,差几百倍很正常,所以缺页率哪怕只高一点,EAT也会被拖垮。这就是为什么抖动会「瞬间摧毁系统性能」——数学上就能体现出来。
我在复习时最喜欢给自己出这道综合题:同一引用串,空物理块3个,FIFO、LRU、OPT三种算法各算一遍缺页率。做完之后就再也不会把三种算法搞混了。你们可以拿上面的引用串 1,2,3,4,1,2,5,1,2,3,4,5 自己练一遍,结果对不上没关系,过程对,分数就能拿。
4. 抖动与工作集:疑难考点里最容易被绕进去的两个概念
4.1 抖动的成因链与补救措施
抖动,又叫做颠簸,是页面置换这块最容易失分也最容易讲不清的名词。我见过非常多人背「抖动就是频繁换页」,但考场上给的题往往是「系统抖动的原因是什么?如何预防?」直接用链式逻辑答:
因为运行的进程太多,或者每个进程分配到的内存块太少,导致一个进程刚被换出的页面,马上又被重新访问,于是反复缺页、反复换页。缺页率飙涨之后,CPU大部分时间都在等磁盘I/O,利用率反而急剧下降。操作系统一看CPU太闲,觉得是负载不够,又往系统里塞更多进程,进一步压缩每个进程的驻留集,缺页更严重,于是彻底陷入恶性循环。
要预防抖动,主要手段有几个方向:一是采用局部置换策略,让一个进程只能换自己的页面,不允许别人把自己的页面抢走;二是引入工作集模型,让进程驻留集不小于工作集,从源头避免缺页爆炸;三是「挂起」若干进程,把物理内存释放出来给剩余进程;四是让操作系统通过「缺页间隔」动态调整驻留集大小。
面试官如果要往深里问,会问你「怎么判断系统开始抖动了?」通常答:观察缺页率和CPU利用率的背离——CPU利用率低但磁盘I/O极高,且进程频繁阻塞,那大概率就抖了。这个判断逻辑,比只背定义值钱得多。
4.2 工作集模型:怎么划定程序的「主力部队」
工作集是理解抖动的钥匙。计算机界的前辈提出了工作集模型,核心思想是:在一段时间Δ窗口内,进程所有访问过的页面的集合,就是它的工作集。
意思就是,程序在某个时间段真正频繁使用的页面,其实就那么多。只要让这些页面始终留在内存里,程序性能基本不受影响。局部性好的程序,工作集稳定且小;局部性差的程序,工作集飘忽不定,那虚拟存储器的调页压力就大。
要注意区分两个极容易混的概念:工作集和驻留集。工作集是进程「客观上需要的」页面集合,是程序行为决定的;驻留集是操作系统「实际分配给你的」页面集合,是管理和调度决定的。只要驻留集小于工作集,缺页就会开始频繁发生,抖动就开始酝酿。反过来,如果驻留集能始终覆盖或者接近工作集,系统就能平稳运行。
答简答题时最值钱的展开是:工作集窗口Δ大小的选择,本质是一个权衡——窗口太大,工作集包含的页面偏多,内存压力大;窗口太小,工作集不能真实反映局部性。这个权衡点被问到的概率不低,提前理解比临时背答案稳。
4.3 驻留集大小的动态调整策略
关于驻留集,还有两个维度的考点:固定分配和可变分配、局部置换和全局置换。把它们一一拆开,这块就通了。
固定分配指给每个进程分配固定数目的物理块,运行期间不变;可变分配指根据缺页情况动态增减。局部置换指缺页时只从自己的物理块里选页面淘汰,换完仍然归自己;全局置换是缺页时直接从全局空闲块或者甚至抢别人的页面来用。这两组变量之间有经典搭配,比如「固定分配局部置换」简单但灵活性差,「可变分配全局置换」灵活但一个进程可能挤占其他进程资源,「可变分配局部置换」则是最常用的平衡方案,缺页时增设物理块,不频繁缺页时减少,整体趋稳。
动态调整的经典策略就是缺页间隔的反馈控制:如果某进程缺页间隔过短,说明驻留集不足,给加点物理块;如果缺页间隔很长,说明内存给多了,适当收回来给其他进程。这正好呼应抖动的预防思路——操作系统不是一次性拍板分你多少内存,而是持续监督、动态修正。考试如果出论述题,把「固定/可变、局部/全局、动态反馈」三个概念串成一个逻辑讲清楚,整个章节的深层理解就体现出来了。
5. 虚拟存储器与进程的「肉身」:内存映射与共享内存
5.1 内存映射文件:为什么大文件加载可以「秒开」
很多人学到虚拟存储器就止步于页面置换,但其实虚拟存储的思想在操作系统很多地方都有体现,内存映射文件就是最典型的一个。它的思路是:把磁盘上的文件内容,直接映射到进程的虚拟地址空间中。进程访问这块虚拟地址时,就像访问内存一样,操作系统在后台按需把对应页从磁盘调入。
所以你打开一个几GB的大文件,往往「秒开」——因为打开操作根本没有真正读入内容,只是在页表里建立了映射关系。当你要读其中某一段,那一页才真正进内存。这就是「把文件的IO变成按需调页」的思路,和虚拟存储器的懒加载一脉相承。
这个知识点在简答题里出现,通常以「什么是内存映射?有什么优点?」形式呈现。答题要点就是三条:用虚拟内存思想方便访问、减少系统调用次数、结合按需调页实现部分文件加载。面试如果聊到IO模型,把内存映射和虚拟存储器联系起来说,会让面试官觉得你不是碎片化理解的。
5.2 写时复制与共享页面
另一个由虚拟存储器派生出来的经典话题是写时复制。父进程调用创建子进程时,通常不会把父进程的所有页复制一份给子进程——那太浪费了。操作系统直接让子进程和父进程共享同一批物理页,并且把这些页标记为「只读」。只要双方都不写,大家共用同一片内存,相安无事。
一旦某一方想往共享页里写数据,硬件会触发一个保护异常,操作系统介入,复制一份物理页给写入方,让写入方在这个新副本上写。这就是写时复制。好处显而易见:进程创建变快,内存开销大幅降低;坏处是如果子进程上来就大量写,复制成本会集中爆发。
这道题的常考问法是「为什么写时复制能节省内存」,答题思路是:延迟复制,只在真正发生写入时才复制页面,大部分场景下父子进程都大量共享代码段和只读数据,真正需要复制的页面很少。这个「延迟分配」的思想,和请求分页的「按需调入」本质是同一个哲学——把资源的实际消耗,拖延到真正需要的那一刻。
5.3 页面大小与地址变换的性能权衡
还有一类简答题很爱出:「页面大小应该大还是小?理由是什么?」这题没有绝对答案,本质是权衡。
页面偏小,内部碎片小,物理内存浪费少;页面小还意味着换入换出的粒度小,单个页的传输时间短。但坏处也明显:页表会很长,页表本身占的内存多;地址变换时查表次数多;磁盘往返次数会变多,IO开销的固定成本反而被放大。
页面偏大,页表短了,查表快了,IO次数少了,但内部碎片增多,而且换页时连不用的部分也一起搬进内存,一次性开销变大。更关键的是,局部性不好时大页会让工作集被高估,内存压力也随之变大。
写这道题时,最稳妥的作答结构是「先说影响因素,再分点论述大小各有利弊,最后给出一个折中线」。比如工业界常见4KB页,但现代CPU和系统也支持大页。你可以加一句「大页常用于减少TLB缺失、提高频繁访问大内存场景的性能」,这句话属于锦上添花,能展示你见过真实工程场景。
顺带提醒一句:页表太长的问题,实际系统里还有「两级页表、多级页表」来解决,这部分虽然不完全属于虚拟存储器本章的调页范畴,但它和地址变换、页表结构直接相关。复习时把多级页表、快表的逻辑一起梳理,整个章节的底层原理更扎实。
6. 简答题答题套路:从「背概念」到「会踩得分点」
6.1 概念型简答题的标准答题结构
最后重点聊聊怎么答题。很多考生知识点都懂,一写就丢分,原因是答题太「平」——只有一句定义,没有层次。我总结了一个万能的答题结构:定义 → 原理/机制 → 作用/影响 → 边界/易错点。前三个层次是基本盘,第四个层次是拉分项。
举「什么是虚拟存储器?」为例。低分答法是:「把磁盘当内存用。」高分答法是:虚拟存储器是指具有请求调入功能和置换功能、能从逻辑上对内存容量加以扩充的一种存储器系统(定义);其实现基础是局部性原理,基于请求分页或请求分段机制,即将作业的一部分装入内存即可运行,其余部分根据需要调入(原理机制);它实现了内存的逻辑扩充,使小内存可以运行大作业,提高了内存利用率和多道程序并发度(作用);但虚拟存储器的实现需要页表、缺页中断、页面置换等机制配合,且页面的频繁换入换出会带来外存I/O开销,若驻留集不足还会导致抖动(边界)。你看,同样的知识点,层次一拉开,分数自然拉开。
6.2 计算型题目的标准解题步骤
简答题卷子上虽然侧重文字,但计算和机制分析才是快速拉开差距的地方。拿缺页率计算题举例,标准答题流程是:先把引用串抄到答题纸的左侧,画一个物理块数的表格,表头写块号。每次访问一个页,先看是否在表中命中,命中写H并修正访问顺序(特别是LRU);未命中写F,然后根据算法淘汰对应页并把新页填入。
这里有个特别要提醒的步骤:LRU模拟时,很多人不知道要在表里记录每一行的「最近使用时间」,导致后边淘汰时不知道踢谁。我的建议是,在页面号旁边顺手标一个使用时间序号1、2、3……每次访问时更新。草稿纸上有这个标记,整个模拟快一倍,也稳一倍。
计算EAT时,一定要把单位统一,别出现「内存访问100ns、缺页中断8毫秒」然后把两个数直接相加。先换成纳秒或者毫秒再算,最后答案保留有效位数。这些细节看着傻,实际丢分的人不在少数。
6.3 我踩过的坑与判卷视角的提醒:这章的易混点清单
作为过来人,我最后把这章最容易混的几个点集中列一下,你们复习时可以对号入座:
缺页中断与普通中断。缺页中断发生在指令执行期间,处理完后要重执该指令;普通中断发生在指令执行之后,处理完接着执行下一条。一个字之差,机制完全不同。这是本章选择题和简答题的超级高频考点。
工作集 vs 驻留集。工作集是程序「需要」的,驻留集是系统「给」的。驻留集小于工作集就会频繁缺页,这就是抖动的判据之一。
页面置换 vs 分段置换。本章主要讨论请求分页,但同样的思想也适用于请求分段,只是请求分段以段为单位调换。考纲如果不要求深挖段页式,至少别把「段内连续、段间离散」和「页式离散」搞混。
外部碎片 vs 内部碎片。分页有内部碎片,分段有外部碎片,很多人提到碎片不看上下文直接答,这种基础错误在虚拟存储器章节很致命。
复习这章的时候,我个人的一个土办法是:把每一个名词都按「选择题选项、简答题得分点、论述题素材」三个角色想一遍。比如「页面置换算法」你先能选择题不掉坑,再能默写三大算法区别,最后能讲清楚Clock为什么替代纯LRU。这样无论是应对考研的简答题,还是应试模式下的工作面试,这个章节就是一个稳稳的得分板块。
顺带分享个我自己的经历:有一回模拟面试,对方让我手写LRU的思路,我第一反应写了个基于链表的实现,然后被追问「你这种实现的时间复杂度和成本呢?」一下就暴露了我没想过工程权衡。从那次之后,我养成了一个习惯——每个算法都先问一遍「理论版本长什么样?工业版为什么改?改了什么?」这个习惯,对这章的帮助比死记硬背大得多。