操作系统学到第五章基本就到了一个分水岭前面几章在解决CPU怎么调度、进程怎么切换、同步互斥怎么做从这一章开始系统把重心转向内存。内存管理的知识点在大多数教材里都安排在第五章附近概念密度特别高而且非常容易出计算题——地址转换、页面置换、碎片计算全是能在卷面上拦人的地方。这篇内容就是针对操作系统第五章课后习题做的完整解析。我不打算把答案简单贴在最后而是把习题背后的知识点、推导过程和易错点一并讲清楚。整篇按四个层次安排先把第五章的核心考点梳理一遍再逐类拆解选择题、判断题、简答题和计算题最后单独列一份避坑清单。正在做课后作业、准备期中期末或者考研复习到存储管理部分的同学都可以直接对照使用。每家教材的章节划分略有差异但内存管理这块内容基本都会出现在第五章附近。下面的解析按最常见的内容组织方式来写从连续分配讲到分页、分段再讲到虚拟存储和页面置换。如果你的教材把文件系统或设备管理放在第五章这部分方向不对但分页、置换思想在后面章节还会复用当提前复习也不亏。1. 第五章到底考什么先做一次知识梳理1.1 内存管理要解决的核心问题内存管理在整门操作系统课里承担的任务可以概括成四件事分配、转换、保护、扩充。分配与回收解决的是“进程要住进内存住哪、怎么住”的问题。早期的连续分配方式实现最简单但会产生碎片于是出现了分页、分段这些非连续分配方式。地址转换解决的是“程序里写的地址和内存里真实地址怎么对应”的问题这是考试最容易出大题的地方。内存保护解决的是“进程之间别串宿舍”的问题一个进程不能越界读写另一个进程的数据。内存扩充则是利用虚拟存储技术让一个比物理内存大得多的程序也能跑起来。这四个问题不是孤立的。分配方式决定了碎片的类型和大小地址转换方式决定了页表、段表的组织结构虚拟存储要借助局部性原理才能避免系统陷入频繁换页的抖动状态。课后习题表面上是考某一个概念其实大多数题都在同时考这几层关系。1.2 四个核心概念地址、分配、置换、保护复习第五章我建议你先在心里建四个关键词的框架。逻辑地址与物理地址是一切的起点。程序编译链接后生成的是逻辑地址运行时由系统转换成物理地址。逻辑地址由页号和页内偏移组成也好由段号和段内偏移组成也好最终都要落到“物理块号乘块大小加偏移”这个公式上。分配方式要分清连续与非连续。连续分配包括固定分区和动态分区动态分区的三种适应算法经常考非连续分配包括分页、分段、段页式它们的比较几乎每次考试都会出现。虚拟内存与页面置换是重头戏。局部性原理、缺页中断、FIFO、LRU、OPT、Clock算法这些东西容易出计算题和简答题。置换算法的核心是谁被换出、谁被换入理解了淘汰策略缺页次数的计算就不难。内存保护与共享这块容易被忽略但判断题很喜欢考。基址寄存器加界限寄存器、页表项里的保护位、段表里的共享标志都是常见考点。1.3 第五章常见题型分布从课后题和历年考题来看第五章题型大概分三类。第一类是概念题包括选择、判断、填空。这类题主要考定义和区别比如内部碎片与外部碎片、分页与分段、虚拟存储的理论基础。第二类是计算题包括逻辑地址到物理地址的转换、有效访问时间的计算、FIFO与LRU缺页次数统计、动态分区分配结果分析。第三类是综合题一般是给一个访问序列让你比较多种置换算法或者给一个内存分配过程让你分析碎片情况。把这三类题吃透第五章基本就稳了。下面进入具体习题解析。2. 选择题与判断题课后习题解析2.1 选择题连续分配方式中的经典套路选择题里最常考的是动态分区分配算法。先看一道典型题。题目在可变分区存储管理中最佳适应算法要求空闲分区按什么顺序排列A. 按地址从小到大B. 按地址从大到小C. 按空间从小到大的顺序D. 按空间从大到小的顺序答案是C。最佳适应算法的思路是为作业选择满足要求的最小空闲分区把可用空间按从小到大排列查找时沿着队列找到的第一个大小够用的分区就是最接近作业大小的那个。这样做的优点是尽量不浪费大块空闲区但缺点是容易留下很多难以利用的小碎片当这些小碎片太多时大作业反而进不来。对比一下另外两个算法首次适应算法把空闲分区按地址递增排列分配时从头开始找找到第一个大小够用的分区就分配最差适应算法按容量从大到小排列优先用最大的空闲区想尽量留出多个相对均匀的空闲区但同样有隐患。这三者的取舍关系课后题经常以“选择正确描述”的形式出现。再来看一道关于碎片的题。固定分区分配方式可能产生的碎片是动态分区分配方式可能产生的碎片是。答案是内部碎片、外部碎片。固定分区把内存切成若干固定大小的区作业小于分区时就有一段空间永远用不上这就是内部碎片。动态分区按需分配但反复申请和释放会在内存中形成许多不连续的小空闲区这些无法被利用的小区段就是外部碎片。还有一个高频选择题分页存储管理中逻辑地址的结构是什么。答案是由页号和页内偏移两部分组成。注意页号位数决定最多支持多少页页内偏移位数由页面大小决定。比如页面大小为4KB页内偏移就是低12位因为2的12次方等于4096。2.2 判断题陷阱为什么对、为什么错判断题看起来轻松其实陷阱不少因为考的是概念的边界。第一题一个进程的逻辑地址空间可以大于物理内存的大小。这句话是对的。虚拟存储技术允许进程的逻辑地址空间超过物理内存程序运行时只把部分页面装入内存其他页面放在外存用到时再换入。很多同学觉得“进程不可能比物理内存还大”恰恰忘了虚拟存储就是要打破这个限制。第二题分页存储管理对用户是可见的。这句话是错的。分页对用户完全透明用户看到的仍然是连续的逻辑地址空间页面如何划分、如何装入物理块都是由系统自动完成的。分段则不一样段是用户按逻辑模块划分的分段对用户可见。这个差别几乎每年都考。第三题内存保护只需要硬件就可以实现。这话也是错的。内存保护需要操作系统和硬件配合。硬件提供基址寄存器、界限寄存器等机制操作系统负责初始化、切换和维护这些寄存器的值两者缺一不可。第四题FIFO页面置换算法可能出现Belady异常LRU算法不会。这句话是对的。Belady异常指物理块数增加缺页次数反而增加。FIFO因为完全不考虑访问频率可能出现这种情况LRU基于最近的访问历史淘汰页面从理论上看增加物理块不会让缺页次数上升。这类判断题最好的复习方式就是在课本原文里找出处。概念判断题的正确答案往往是教材原话的转述而错误选项通常是把“分页”和“分段”、“内部碎片”和“外部碎片”故意互换一下。2.3 选择题中的参数计算别忽略快表命中率选择题里有一类问题表面是概念实际要算数就是有效访问时间。典型题目某分页系统内存访问时间为100ns快表的访问时间为10ns快表命中率为80%求有效访问时间。快表命中的情况下CPU需要先查快表再访问一次内存取数据所以耗时是快表时间加内存时间也就是10加100。快表未命中时需要先访问内存中的页表再访问内存中的数据共两次内存访问耗时是快表时间加两倍内存时间。有效访问时间等于两种情况按概率加权平均有效访问时间 0.8乘以(10 100) 0.2乘以(10 200) 88 42 130ns。如果没有快表每次都要访问两次内存有效访问时间固定是200ns以上。快表的作用就是尽量让大部分访问只查一次内存这也是分页系统必须配快表的原因。3. 简答题与论述题这样答才拿高分3.1 局部性原理虚拟存储的理论基石简答题里出现率最高的一道就是问虚拟存储的理论基础是什么。标准答案核心是局部性原理。答题时至少写两点。时间局部性程序刚访问过的数据很可能在不久之后再次被访问。典型场景是循环体里的变量和指令循环会反复执行同一段代码。空间局部性程序访问某个地址附近的数据时它附近的数据在接下来也会很快被访问。典型场景是数组和顺序执行的指令流程序往往连续访问相邻存储单元。再往上答一层程序执行的局部性原理使得程序在运行过程中没有必要把全部代码和数据都放入内存。系统只需要把当前正在使用的部分页面装入内存其他部分留在外存当访问的页面不在内存时再通过缺页中断调入。这就是虚拟存储能够“以小博大”的根本原因。避免只答理论不举例。考试时加上“循环语句”、“数组遍历”两个例子老师印象会好很多。3.2 分页与分段的区别一张表解决分页和分段的区别属于必背内容但很多同学背了忘、忘了背。我习惯用一张表来对比。对比维度分页存储管理分段存储管理划分方式按固定大小划分页面按程序的逻辑模块划分段地址空间一维地址空间二维地址空间对用户可见性对用户透明对用户可见内存碎片主要产生内部碎片主要产生外部碎片共享与保护不方便按逻辑单元共享便于按段共享和保护内存管理开销页表开销与页面大小相关段表开销与段数相关分页是从内存管理的角度看问题目的是提高内存利用率用户感受不到分段是从用户和程序员角度看问题每个段是一个相对完整的逻辑单元比如代码段、数据段、栈段方便编译器和链接器处理也方便共享和保护。如果题目进一步问段页式存储管理答法就是先把程序按逻辑分段再把每一段按固定大小分页这样既具备分段便于共享保护的优点又具备分页减少外碎片、提高内存利用率的优点。代价是地址转换需要经过段表和页表两级访问时间变长需要快表加速。3.3 页面置换算法比较从淘汰策略到适用场景简答题问置换算法时不能只写一句话定义。我的答题框架是策略、优点、缺点、典型现象四层都写到。FIFO代表先进先出算法。淘汰最早进入内存的页面。实现简单用一个队列就能搞定但完全不考虑页面被访问的频率可能把正在频繁使用的页面换出而且会出现Belady异常。LRU代表最近最久未使用算法。淘汰最长时间未被访问的页面。依据程序的局部性原理性能比FIFO好也不会出现Belady异常但需要记录每个页面的访问时间或维护访问序列硬件开销较大。OPT代表最佳置换算法。淘汰未来最长时间不被访问的页面。理论上缺页率最低但需要预知未来的访问序列现实中无法实现因此通常作为衡量其他算法优劣的标准。Clock代表时钟置换算法也叫二次机会算法。每页有一个访问位循环扫描遇到访问位为0的页面就淘汰否则把访问位清0并继续查找。它是LRU的近似实现开销比LRU小实际操作系统用得比较多。论述题如果问“为什么OPT只能作为评价标准”要明确说因为系统不可能知道进程未来会访问哪些页面这只是一种理论上的极限。4. 计算题分页、分段、置换算法的完整演算4.1 逻辑地址到物理地址的转换地址转换属于送分题但每年仍有不少人算错。我按步骤拆一遍。题目某分页系统页面大小为1KB某进程的页表内容为页号0对应物理块号2页号1对应物理块号6页号2对应物理块号4页号3对应物理块号9。给定逻辑地址2500求对应的物理地址。第一步把页面大小换算成字节。1KB等于1024B。第二步计算页号和页内偏移。页号等于逻辑地址除以页面大小取整数商页内偏移等于逻辑地址对页面大小取余。2500除以1024商是2余数是452。所以页号是2页内偏移是452。第三步查页表。页号2对应的物理块号是4。第四步计算物理地址。物理地址等于物理块号乘以页面大小再加上页内偏移。这里就是4乘以1024加452等于4096加452结果是4548。有几个坑必须提醒。页面大小不是4096时不少人还习惯性用4096去乘这是错的。物理地址计算用的是物理块号不是页号更不能拿逻辑地址直接去加。另外如果页号在页表中查不到说明页面不在内存应该触发缺页中断而不是继续计算。这类题还有一种变体给十六进制地址。先把16进制转成10进制或者用二进制拆分。页面大小为4KB时逻辑地址的低12位是页内偏移剩余高位是页号熟练之后可以直接在二进制里截位。4.2 页面置换算法缺页率计算FIFO与LRU完整演算页面置换算法的计算题是完全套路化的关键在于一步步画表格。看一个经典序列。访问序列1, 2, 3, 4, 1, 2, 5, 1, 2, 3, 4, 5物理块数3分别计算FIFO、LRU、OPT的缺页次数。所有算法默认初始物理块为空首次加载也算缺页。先看FIFO。访问页物理块1物理块2物理块3是否缺页11--缺页212-缺页3123缺页4234缺页1341缺页2412缺页5125缺页1125命中2125命中3253缺页4534缺页5534命中FIFO共缺页9次。再看LRU。LRU淘汰最长时间未被使用的页面每次命中要把这一页的“最近使用状态”更新。访问页物理块1物理块2物理块3是否缺页11--缺页212-缺页3123缺页4234缺页1341缺页2412缺页5125缺页1125命中2125命中3123缺页4234缺页5345缺页LRU共缺页10次。最后看OPT。OPT需要向后看每个页面下一次出现的位置淘汰下次使用最远的页面。前三次依次缺页物理块为1、2、3。访问4时向后看页面1在第5次出现页面2在第6次出现页面3在第10次才出现因此淘汰3。之后1和2都命中。访问5时物理块是1、2、4向后看1在第8次2在第9次4在第11次淘汰4。之后1、2命中。访问3时物理块是1、2、5向后看1和2在后面都不再出现5在第12次出现从1和2中任淘汰一个即可。之后访问4再淘汰另一个不再出现的页面最后5命中。OPT共缺页7次。这组结果很能说明问题OPT缺页最少LRU比FIFO多一次看起来FIFO还更少。千万别因此得出FIFO比LRU好的结论。这个访问序列的特殊性在于FIFO恰好碰巧换个局部性强的序列LRU通常更好。而且把物理块数从3增加到4时FIFO缺页次数会从9次增加到10次这就是Belady异常。不妨动手验算一遍印象会很深。4.3 缺页次数计算时的统一约定计算缺页次数最容易引起争议的是初始加载算不算缺页。统一约定是只要访问的页面不在内存物理块中就算一次缺页。初始状态物理块为空第一次装入当然不在内存中所以算缺页。考试如果出现选择或填空答案一般都按这个约定算。除非题目明确说明物理块已经预装好否则不要自作主张减去前几次。另一个容易踩的坑是算法内部“队列顺序”和“物理块内容”混在一起。FIFO判断谁先进入LRU判断谁最久没被访问两者淘汰的对象不同。计算时一定要在表格旁边记录淘汰对象的理由这样检查时才能迅速发现错误。4.4 动态分区分配与碎片计算再讲一类计算题给一个内存分配过程算分配位置和碎片大小。题目内存容量128MB初始为一个连续空闲区。作业A申请40MB作业B申请50MB连续分配后A释放作业C申请30MB。分别按首次适应和最佳适应算法分析C的分配位置和产生的碎片。初始空闲区是0到127MB。第一次分配A占用0到39MB空闲区变成40到127MB共88MB。第二次分配B占用40到89MB空闲区变成90到127MB共38MB。A运行结束后释放空闲区变成两块0到39MB共40MB90到127MB共38MB。首次适应算法把空闲区按地址递增排列查找时从低地址开始。C申请30MB首先看到0到39MB这块40MB的空闲区大小足够于是C分配到0到29MB。这块空闲区剩下10MB加上原来的38MB空闲区总空闲48MB但低地址端留下一个10MB的小碎片。最佳适应算法把空闲区按容量递增排列。两块空闲区分别是40MB和38MBC申请30MB时最佳选择是38MB那块因为40MB那块虽然也能放但不必要地消耗更大的连续空间。于是C分配到90到119MB剩下120到127MB共8MB碎片。两种情况都会产生外部碎片只是大小不同。第一次适应留下10MB小碎片最佳适应留下8MB小碎片。这题告诉我们所谓“最佳”只是针对当前分配使剩余空闲区尽可能小并不保证整体碎片最少。还有一种常见的内碎片计算题页面大小4KB某进程大小10KB需要分配多少页最后一页产生多少内碎片10KB除以4KB商2余2KB所以需要3页。前三页共12KB进程实际使用10KB最后一页浪费2KB。这类题信息很直白只要记住“页数向上取整浪费在最后一个页内”就能做对。5. 易错点与备考建议5.1 最容易踩的五个坑我批改和答疑时经常看到以下错误列出来供自查。第一个坑混淆逻辑地址和物理地址。地址转换题里逻辑地址的页号来自地址本身物理地址里的块号来自页表两者不能混用。做题时先把逻辑地址拆成页号和偏移再查页表最后计算物理地址顺序不能跳。第二个坑忘记初始缺页。统计缺页次数时很多同学在第一次装入时写“命中”这是致命的错误。所有页面置换算法题目初始物理块为空第一次访问全部算缺页。第三个坑把分页和分段碎片搞反。分页固定大小进程最后一页用不满产生内部碎片分段按逻辑模块分反复申请释放产生外部碎片。判断题一旦把互换基本就错了。第四个坑计算有效访问时间时分不清快表命中和未命中的内存访问次数。快表命中只需要访问一次内存未命中需要访问两次内存因为第一次取页表项第二次取数据。题目给两个时间一定要代入公式算不要凭感觉。第五个坑FIFO队列顺序被“访问命中”打乱。FIFO只看页面进入内存的时间。即使页面刚刚被访问过只要它在内存里驻留时间最长到期一样要淘汰。很多同学在命中时把页面移到队尾等于把FIFO做成了LRU这是概念混淆。5.2 复习时怎么高效利用这份答案课后习题答案不是用来抄的是用来校验理解的。我建议按三步走。第一步先独立做题再把答案逐行对。不要边看答案边做题否则脑子里留下的全是“好像会了”的假印象。第二步计算题必须重画流程。地址转换题画页表置换算法题画物理块变化表分区分配题画内存布局图。哪怕最后结果对也要把过程画一遍因为考场上真正扣分的地方是过程。第三步把错题对应的知识点标注在教材目录上。如果连续三次错同一类题比如一直是缺页统计出错那就要回到局部性原理和置换算法那一节把算法定义重新读一遍。还有一个很管用的方法就是互相讲题。找一个同学你给他讲一遍“为什么FIFO在这个序列上比LRU缺页少”你能从头讲清楚说明你是真会了。讲不清的地方往往就是你理解还模糊的地方。5.3 考前速记清单最后给一份第五章的速记清单背熟它常规题基本不会丢分。动态分区三种算法首次适应按地址递增最佳适应按容量递增最差适应按容量递减。固定分区产生内部碎片动态分区产生外部碎片分页主要内部碎片分段主要外部碎片。虚拟存储的理论基础是局部性原理包括时间局部性和空间局部性。快表命中一次内存访问快表未命中两次内存访问。FIFO可能出现Belady异常LRU和OPT不会。OPT无法实现只能用来评价其他算法。页面大小4KB时物理地址等于物理块号乘以4096再加上页内偏移。缺页次数统计时初始物理块为空第一次装入也算缺页。我个人备考时印象最深的就是那道经典页面置换序列。第一次硬算FIFO缺页次数怎么数都差一次后来改用表格一列一列标“缺页”和“命中”视野一下就清晰了。从那以后我发现第五章的计算题最怕的不是公式不会而是脑子里的流程是乱的。只要你愿意把每一步写在纸上这类题其实是整门操作系统里最好拿分的地方。答案可以帮你核对但复习不能只对答案。每错一道题都值得回到课本那一小节把原文重读一遍把概念重新梳理一遍。真正理解原理之后你会发现课后习题的变化再多核心始终是那十几件事。