从考研复习到系统编程,存储管理里的“页面置换算法”是绕不开的一环。这篇笔记补的是 OS 内存管理中很关键的一页:当访问页面不在内存、内存又已经满员的时候,操作系统到底该把哪个旧页面请出去,让新的页面进来。页面选得好不好,直接决定程序是流畅跑完还是不断陷入磁盘 IO 的泥潭。这篇内容会围绕 OPT、FIFO、LRU、Clock 以及真实系统中的近似实现展开,适合正在准备操作系统考试、面试,或者想搞明白自己写的服务为什么频繁 swap 的读者参考。
前几篇笔记聊了分段、分页、页表、虚拟内存结构,那是地址转换的“静态地图”;页面置换则是运行时最动态的部分。你写一个程序,不管代码多大,物理内存永远有限,操作系统只能把当前最需要的页留着,其他页先送进磁盘交换区。缺页了,才临时去磁盘捞。说白了,页面置换是一道资源紧张时的“淘汰决策题”,决策质量高不高,缺页率说了算。
1. 先弄清页面置换在存储管理里的位置
1.1 从虚拟存储到缺页中断的基本链路
早期操作系统搞存储管理,经常是“哪段程序还在内存里才能跑”。虚拟存储技术打破了这个限制,进程不需要把所有代码和数据一次性加载进物理内存,只需要保证当前执行到的页面在内存即可。程序看到的是一个连续的巨大虚拟地址空间,实际使用哪一页,由 CPU 访问地址时查询页表来定位。
如果页表项里 Present 标志位为 0,也就是这一页不在物理内存,CPU 会触发缺页异常。缺页异常不是错误,它更像“这块数据不在手边,得去仓库取”的信号。操作系统拿到这个信号后,先检查这块虚拟页是否合法,再从磁盘交换区或缺页设备中把页面读到物理页框。如果当时物理内存有空闲页框,过程很简单:读盘、更新页表、恢复进程执行。麻烦的是内存没有空闲页框,这时候就必须在现有页面里挑一个牺牲者,把它换出去,再把新页面换进来。这个“挑牺牲者”的规则,就是页面置换算法。
把页从内存换到磁盘叫做“换出/淘汰”,把磁盘页面调入内存叫“换入”。页面置换算法研究的就是换出策略。有人觉得硬盘空间够大就行,不是这样的。内存访问是纳秒级别,磁盘乃至 SSD 随机访问通常要几十微秒甚至更高,速度差了两三个数量级。哪怕 1000 次访问里只缺页 1 次,整体性能也会明显下跌。如果在真实服务器上看到内存指标打满后进程响应突然变慢,极可能就是缺页和换页在拖后腿。
1.2 缺页时真正要回答的问题:谁先走
理解页面置换算法其实有一个很简单的锚点:不管算法名字多花哨,它每次缺页时回答的都只是“当前哪个页框被选中淘汰”。
判断一个置换算法好不好,主要看三件事:缺页率是否足够低、单次置换开销是否可控、算法本身能不能在真实硬件上实现。前两者很容易理解,第三个最容易被初学者忽略。比如最优置换算法 OPT 显然缺页率最低,但它要预知未来的访问序列,现实系统不可能知道进程下一秒会访问哪一页,所以只能当作理论标杆。再比如 LRU 在模拟器上表现很好,但要精确记录每个页最近一次访问是几十毫秒前还是几微秒前,硬件支持成本很高。操作系统设计者必须兼顾算法效果和实现成本,这正是 Clock 算法和它的各种改良版能在工业界流行的根本原因。
页面置换的知识结构并不复杂,却很容易让人越学越乱,原因在于算法之间不是简单的谁优谁劣。有些算法是“根据过去预测未来”,有些是“先来先占”,还有些是“参考了访问频率和修改状态组合决策”。把这些算法放一起对比,先看它们各自在干什么,再看为什么现实中往往不用教科书黄金算法,这样才算真正吃透。
1.3 理解局部性原理是前提
前面说的“选谁先走”好像是在猜未来,但计算机科学里有个很强大的经验规律:局部性。一个进程在某段时间内访问的地址空间,往往集中在很小的范围内。循环会反复压同一段指令,数组遍历会连续访问相邻数据,调用栈也总是围绕栈顶附近。正因局部性的存在,页面置换才有规律可循:刚刚被访问的页,很可能在接下来很短时间里又被访问;已经很久没被访问的页,大概率未来一段时间内也不会被访问。
局部性分为空间局部性和时间局部性。页面置换算法主要利用时间局部性。你可能刚开始学时会想,如果算法完全不看访问历史,随便选页行不行?随机淘汰虽然避免了很多麻烦,但不如 LRU 这类利用局部性的算法稳定,因为它没把“哪些页更可能被用到”这个重要信息放进决策。理解局部性之后,再看 FIFO 为什么偶尔表现不如 LRU,就非常清楚:FIFO 只按进入内存的先后排序,完全不关心这个页被访问得有多热。
局部性还是一个度的问题。如果程序的“工作集”本身已经大于可用的物理页框,那么无论页面置换算法多聪明,再多的历史信息也救不了场,最终会走向系统抖动。这个概念后面我会专门讲,它是页面置换算法的边界条件,很多人学到 4.3 节才发现前面算法的前提其实很苛刻。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 经典置换算法逐个拆解
2.1 OPT 最优置换:理想标准,无法实现但价值极高
最优置换算法的思想简洁到不像算法:当发生缺页需要淘汰页面时,选择未来最长时间内不再被访问的页面。如果未来永远不会再访问,那就更该它走。
举个例子,内存里目前有页面 A、B、C,接下来 CPU 即将访问的顺序是 A、D、B...,那么把 C 换出去就是最理想的,因为 C 在未来最远才用到。OPT 的缺页率是所有置换算
