1 先进先出算法(FIFO)
1.1 基本思路:
选择在内存中驻留时间最长的页面并淘汰之. 具体来说, 系统维护着一个链表, 记录了所有位于内存当中的逻辑页面. 从链表的排列顺序来看, 链首页面的驻留时间最长, 链尾页面的驻留时间最短. 当发生一个缺页中断时, 把链首页面的淘汰出局, 并把新的页面添加到链表的末尾.
1.2 评价:
性能较差, 调出的页面有可能是要经常要访问的页面, 并且有Belady现象. 很少单独使用.
2 最近最久未使用算法(LRU)
2.1 基本思路
当一个缺页中断发生时, 选择最久未使用的那个页面, 并淘汰之.
2.2 原理
它是对最优页面置换算法的一个近似, 其依据是程序的局限性原理, 即在最近一小段时间内, 它们还可能会再一次被频繁的访问. 反过来说, 如果在过去某些页面长时间未被访问, 那么在将来它们还可能会长时间地得不到访问.
2.3 评价
LRU算法需要记录某个和页面使用时间的先后顺序, 开销比较大, 两种可能的实现方法是:
- 系统维护一个页面链表, 最近刚刚使用过的页面作为首节点, 最久未使用的页面作为尾节点. 每一次访问内存时, 找到相应的页面, 把它从链表中摘下来, 再移动到链表之首, 每次缺页中断发生时, 淘汰链表尾部的页面.
- 设置一个活动页面栈, 当访问某页时, 将此页号压入栈顶, 然后考察栈内是否有与此页面相同的页号, 若有则抽出. 当需要淘汰一个页面时, 总是选择栈底的页面, 它就是最久未使用的.
3 时钟页面置换算法
时钟页面置换算法, LRU的近似, 对FIFO的一种改进.
3.1 基本思路:
- 需要用到页表项当中的访问位, 当一个页面被装入内存时, 把该位初始化为0, 然后如果这个页面被访问(读/写), 则把该位置为1.
- 把各个页面组织成环形链表(类似钟表面), 把指针指向最老的页面(最先进来).
- 当发生一个缺页中断时, 考察指针所指向的最老页面, 若它的访问位为0, 立即淘汰, 若访问位为1, 则把该位置置为0, 然后指针往下移动一格. 如此下去, 直到找到被淘汰的页面, 然后把指针移动到它的下一格.
3.2 流程
时钟页面置换算法图示:
1. 假设内存中有四个物理页帧, A, B, C, D, 某一时刻有四个逻辑页面a, b, c, d与其对应(lp代表最末指针):
2. 假设此时来了一堆逻辑页号的访问请求序列: c, a, d, b, e, b, a, b, c, d, 那么有在访问前四个页号c, a, d, b时都不会产生缺页中断, 但是在访问逻辑页号e时, 此时e会产生缺页中断, 那么此时需要找到被替换的逻辑页, 此时lp指向a, 但是a所对应的物理页帧A的访问位是1, 所以把A的访问位置为0, 然后指针移向b:
3. 这次循环下去发现b c d的访问位都是1, 所以都置为0, 然后lp回到a:
4. 发现a对应的A的访问位是0, 那么把其替换为e, 并把e的访问位置为1, 把lp移到b:
5. 访问b的请求来了, 把b对应的B的访问位置为1:
6. 访问a的请求来了, 产生缺页中断, 此时lp在b, 但是b的访问位为1, 那么置为0, 然后吧lp移向c, 发现c的访问位是0, 直接替换为a, 并把访问位置为1, 把lp移向d:
7. b的访问请求来了, 没有产生缺页中断, 把b的访问位置为1:
8. c的访问请求来了, 产生缺页中断, 此时lp在d, 访问位是0, 那么直接替换掉, 访问位置为1, lp移动到e:
9. d的访问请求来了, 产生缺页中断, 此时lp在e, 但是e b a 对应的物理页帧的访问位都是1, 所以转一圈把所有访问位都置为1之后又回到了e, 此时e对应的A的访问位为0, 那么把其替换成d, 且访问位置为1, 然后把lp移至下一位b:
4 二次机会法
clock算法的不足: 将页面置换出去需要写入硬盘, 代价较大. 页表项中不仅有访问位, 还有写入位, 代表着这个物理页帧从硬盘到物理内存后(首次载入或者上次被置换进来)是否被写入过, 如果在置换算法中需要将一个页置换出去, 其对应的物理页帧的写入位是0, 那么不需要将其物理页帧内容写入硬盘, 只需要将其直接释放即可.
二次机会法思路: 与clock算法类似, 也是维护一个环形链表, 当发生页中断时, 检查指针指向的页对应的页表项的访问位和写入位, 如果都是0, 那么直接置换该页. 如果访问位及写入位有且仅有一位是1, 如果访问位和写入位都是1, 那么就把访问位置为0, 写入位置为1.
5 最不常用算法
思路: 缺页中断产生时, 选择访问次数最少的页作为被置换的页.