页面置换怎么做:缺页中断、FIFO、LRU 与时钟算法
围绕分页、缺页中断和页面置换算法,解释物理内存不足时操作系统如何选择页面换出,以及不同策略各自的特点。
相关工具
为什么已经有虚拟内存还会缺页
虚拟内存让进程拥有比当前物理内存更大的地址空间,但并不意味着所有页面都同时驻留在内存中。系统可以只把近期需要的页面放进物理内存,把暂时不用的页面留在磁盘或交换区域。程序访问一个尚未驻留的页面时,就会触发缺页中断。
缺页并不等同于程序错误。操作系统会先判断这个虚拟地址是否属于进程合法的地址空间;如果合法,只是页面暂时不在内存,系统就需要找到空闲页框,或选择一个已有页面换出,再把需要的页面装入。若地址本身没有合法映射,才属于真正的非法访问。
访问页面未命中时,系统检查地址合法性,准备页框并装入所需页面,然后恢复原任务。
页框和页面不是同一个概念
页面是虚拟地址空间中的固定大小区域,页框是物理内存中对应大小的存储位置。页表把虚拟页映射到物理页框,页面可以在不同时间被装入不同的页框。区分这两个概念很重要:页面属于进程的地址空间,页框属于有限的物理内存。
当进程访问一个页面时,如果页表显示它已经驻留,处理器可以继续完成地址转换;如果页表显示它不在内存中,系统就需要处理缺页。物理内存中可用页框数量有限,页面置换算法就是在页框不够时决定换出哪一个已有页面。
页面置换要尽量避免什么
页面置换的直接目标是腾出一个页框,但更重要的目标是减少未来再次缺页的可能。如果刚刚换出的页面马上又被访问,系统就要把它重新装回,同时可能换出另一个页面,形成频繁的来回搬运。这样的情况会让处理器花费大量时间等待存储设备。
理想算法应该换出未来最长时间不会再访问的页面,但系统无法准确知道程序未来的访问顺序。因此实际算法只能根据已经发生的访问记录做近似判断。访问历史越能代表未来,置换效果通常越好;记录历史的成本越高,算法本身的管理开销也越大。
FIFO:最早进入的页面先换出
先进先出算法把驻留页面按进入内存的时间排成队列,发生缺页且没有空闲页框时,换出最早进入的页面,再把新页面放到队尾。它不需要记录每个页面最近是否被访问,实现和理解都比较简单。
FIFO 的问题是“进入得早”不等于“现在不需要”。一个很早装入但一直频繁使用的页面,也可能因为排在队首而被换出。换出后如果马上再次访问,又会产生新的缺页。FIFO 适合作为理解页面置换的起点,却很难单独代表程序的访问习惯。
页面按进入内存的顺序排队,发生置换时优先移出最早进入的页面。
LRU:换出最长时间没有使用的页面
最近最久未使用算法关注页面的访问时间。每次访问页面时,系统更新它的最近使用记录;需要置换时,选择距离上一次访问最久的页面。它利用了时间局部性:刚刚使用过的页面,短时间内再次使用的可能性通常更高。
LRU 比单纯按进入时间排序更贴近程序访问行为,但记录每次访问的顺序需要额外成本。真实处理器和操作系统往往通过访问位、计数或近似结构来减少管理开销,而不是完整保存所有页面的精确时间顺序。
时钟算法:用访问位近似判断新旧
时钟算法把页框组织成类似环形队列的结构,每个页面带有一个访问位。指针检查当前页面:如果访问位为一,说明它近期使用过,就把访问位清零并继续向前;如果访问位为零,说明它较长时间没有被访问,可以作为置换候选。
它不需要精确记录每次访问的时间,却能保留“近期使用过的页面暂时不换出”的信息。指针在环上循环移动,既避免了维护复杂的完整排序,也让页面在长期没有访问时逐步获得被换出的机会。
页面置换和 TLB、页表怎样配合
页面是否驻留、位于哪个页框、是否允许读写,都记录在页表相关信息中。页面被换出时,系统需要更新对应页表项,让下一次访问能够触发缺页处理;新页面装入后,再把虚拟页和新的页框建立映射。地址转换缓存 TLB 中如果还保留旧映射,也需要同步处理。
因此一次页面置换不只是搬运数据,还包括页表状态、脏页写回、权限信息和缓存映射的调整。页面内容被修改过时,换出前通常需要考虑是否写回持久化设备;如果只是只读代码或尚未修改的映射,处理方式可能不同。
页面换出后更新页表,新的页面装入页框并刷新相关地址转换状态。
页面抖动:置换忙,任务推进慢
如果进程的活跃页面集合大于可用页框,运行过程中就会频繁发生缺页。系统不断换出一个页面、装入另一个页面,处理器真正用于执行程序指令的时间反而减少。这种高频置换现象通常被称为页面抖动。
页面抖动说明系统当前分配给任务的物理内存不足,或者多个任务同时争用有限页框。排查时不能只看虚拟地址空间大小,还要观察缺页频率、活跃页面范围、内存压力和存储设备等待。减少并发任务、调整内存分配或改善访问局部性,都可能缓解抖动。
如何比较不同页面置换算法
比较算法时,可以使用同一串页面访问序列,设定相同数量的页框,然后统计缺页次数和置换开销。缺页次数较少通常意味着更好的访问预测,但还要考虑算法维护访问记录需要多少额外工作。一个理论上效果很好的算法,如果记录成本过高,也未必适合实际系统。
FIFO 强调先后顺序,LRU 强调近期访问历史,时钟算法用访问位做近似。它们都在回答同一个问题:当物理内存不够时,哪个页面最可能暂时用不到。理解判断依据,比只记住算法名称和缩写更重要。
用一条主线记住页面置换
页面置换发生在虚拟页面需要访问、但物理页框不足的时刻。系统先判断地址是否合法,再准备页框;如果没有空闲页框,就根据置换策略选择旧页面换出,装入新页面并更新页表与地址转换状态。
FIFO 看进入时间,LRU 看最近访问时间,时钟算法看访问位。无论采用哪种策略,最终目标都是减少不必要的缺页和存储设备等待,让有限的物理内存尽量留给当前真正活跃的数据。
常见问题
缺页中断是不是程序出错?
不一定。合法页面暂时不在物理内存时,缺页中断是虚拟内存正常工作的一部分;只有访问没有合法映射或权限不允许的地址时,才属于非法访问。
为什么 LRU 通常比 FIFO 更合理?
LRU 关注页面最近是否被使用,更贴近程序的时间局部性;FIFO 只看页面进入内存的先后,可能换出仍然频繁使用的页面。
页面抖动说明什么问题?
它通常说明活跃页面超过了可用页框,系统频繁换入换出,存储设备等待占用大量时间,程序本身因此推进缓慢。