页框回收
3.2.4 解决了”淘汰谁”,但留下一个工程问题:淘汰的动作本身太贵。
每次缺页都要”选一页 → 若脏则写回磁盘 → 再从磁盘读入新页”,一次缺页最多要做两次磁盘 I/O。而且一旦选错、刚淘汰的页马上又被访问,还得再读回来。
这一节讲的就是怎么把这个代价降下来。
机制
页面缓冲算法(PBA)
核心思想只有一句:
被淘汰的页面不立即”扔掉”,而是先在内存里挂一会儿;如果很快又被访问到,直接捞回来,省掉一次磁盘 I/O。
具体做法是维护两条链表:
① 空闲页框链表——保存未被修改(干净)的被淘汰页所占的页框。
这些页的内容其实还在内存里,只是”名义上”已经不属于原进程了。若原进程很快又访问该页,系统直接从链表里把它摘回来重新挂上页表即可,一次磁盘读都不需要。
② 修改页面链表——保存已被修改(脏)的被淘汰页所占的页框。
这些页迟早要写回磁盘,但不必立刻写。系统等到链表上积累了足够多的脏页时,一次性批量写回。
两条链表各自省掉了什么
这个设计的精妙之处在于,两条链表解决的是两个不同的浪费:
空闲页框链表省的是”读”——赌的是”刚淘汰的页可能马上还要用”。这实际上是给了被淘汰的页一次反悔的机会,弥补了置换算法可能选错的情况。
修改页面链表省的是”写”——把多次零散的小写攒成一次批量的大写。磁盘的特性是寻道时间占大头,一次写 1 页和一次写 20 页的耗时差别不大,所以批量写回能极大摊薄单页的写入成本。
由此得到本节最重要的一条结论:
有了页面缓冲算法,即使采用 FIFO 这样简单的置换算法,性能也能接近 LRU。
因为选错了还能从空闲链表里捞回来,算法本身的精度就不那么关键了——这正是它的价值所在:用一点内存换取对置换算法精度的宽容。
页框回收机制
上面讲的是”淘汰之后怎么处理”,而页框回收关心的是另一件事:系统什么时候、按什么策略主动去腾出页框。
如果等到缺页发生时才现找页框,进程就必须阻塞等待整个”选页—写回—读入”的过程。更好的做法是提前准备:
设置两个阈值——当空闲页框数低于下限时,唤醒专门的回收进程开始回收;回收到高于上限时停止。
这样系统手里始终有一批现成的空闲页框,缺页时可以直接取用,无需等待。把”同步等待”变成了”异步预备”,这是它与页面缓冲算法配合的地方。
回收的对象按代价从低到高:
- 干净的文件映射页——直接丢弃,零 I/O
- 脏的文件映射页——写回原文件
- 匿名页——必须写到对换区,代价最高
这个顺序解释了为什么系统内存吃紧时,最先被丢掉的总是页缓存。
边界
页面缓冲算法 vs 置换算法
两者不在一个层次上,是配合关系而非替代关系:
- 置换算法回答”淘汰谁”——它仍然要跑(FIFO、LRU、Clock 都行)。
- 页面缓冲算法回答”淘汰之后怎么处理”——它不参与选择,只负责善后。
所以不能说”用了 PBA 就不需要置换算法了”。 正确的说法是:PBA 降低了置换算法选错的代价,从而允许使用更简单的置换算法。
被放进空闲页框链表的页,还算不算在内存里
这是个有点绕但值得想清的点。
从进程的角度看:不算。 该页的页表项存在位已被置 0,进程再访问它仍会产生缺页中断。
从物理角度看:还在。 页框里的内容并没有被清除或覆盖。
所以缺页中断处理程序会先检查空闲页框链表,若发现该页还在链表里,就直接把它摘回来、把存在位改回 1,全程不碰磁盘。这次缺页中断的代价,从一次磁盘 I/O 降到了几条内存指令。
修改页面链表不是”不写回”
脏页最终一定要写回,链表只是推迟并合并了这个动作。
推迟带来一个风险:系统崩溃时,尚未写回的脏页会丢失。这与内存映射文件的写回时机是同一类问题——性能与可靠性的权衡,所以系统还会周期性地强制刷盘。
页框回收 vs 页面置换
| 页面置换 | 页框回收 | |
|---|---|---|
| 触发时机 | 缺页且内存已满时,被动 | 空闲页框低于阈值时,主动 |
| 目的 | 腾出一个页框给当前缺页 | 提前储备一批空闲页框 |
| 进程感受 | 必须阻塞等待 | 无感(异步进行) |
一句话:置换是”现用现找”,回收是”提前备货”。
对照速查
| 页面缓冲算法的两条链表 | 存什么 | 省掉什么 |
|---|---|---|
| 空闲页框链表 | 被淘汰的干净页 | 省”读”——可直接捞回,零磁盘 I/O |
| 修改页面链表 | 被淘汰的脏页 | 省”写”——攒够了批量写回 |
| 关键结论 | |
|---|---|
| PBA 的价值 | 用少量内存换取对置换算法精度的宽容 |
| 效果 | 配合 PBA 后,FIFO 的性能可接近 LRU |
| 与置换算法的关系 | 配合,不是替代 |
| 回收对象 | 代价 |
|---|---|
| 干净的文件映射页 | 零 I/O,直接丢弃 |
| 脏的文件映射页 | 写回原文件 |
| 匿名页 | 必须写对换区,最贵 |
考点
- 页面缓冲算法的两条链表及各自省掉的是”读”还是”写”
- 配合 PBA 后 FIFO 性能可接近 LRU(本节最常考的结论)
- PBA 与置换算法是配合关系,不是替代
- 被挂入空闲页框链表的页仍会触发缺页中断,但可直接捞回,不碰磁盘
- 页框回收靠上下两个阈值主动触发,是”提前备货”而非”现用现找”
链接
- 🏠 返回总览:操作系统第 3 章:内存管理总览
- ⬅️ 上一节:3.2.5 抖动和工作集
- ➡️ 下一节:3.2.7 内存映射文件
- 🔗 淘汰谁的问题见 3.2.4 页面置换算法
- 📖 名词库:第 3 章名词库