大家好,我叫徐锦桐,个人博客地址为www.xujintong.com,github地址为https://github.com/xjintong。平时记录一下学习计算机过程中获取的知识,还有日常折腾的经验,欢迎大家访问。
进程运行时,若其访问的页面不在内存而需将其调入,但内存已无空闲空间时,就需要从交换空间(磁盘中上)中找到对应的页,替换到内存中一个不经常用到的页。
选择那个内存中需要被替换的页的过程叫页面置换算法。
一、最优页面置换算法
这个只是理想型,此算法不会实现。
在缺页中断发生时,会选择下一次访问该页时间最长的页。这是不可能实现的,因为你不可能知道这个页下一次的访问时间是什么。
二、最近未使用(RNU)
每个页中有R和W位。R如果是1表示该页在内存中被读过,R如果是0表示该页在内存中没被读过。W也一样,W如果是1表示该页被修改过。
算法流程:
在最近未使用替换算法中,R会定期的清零(比如每个时钟周期)。发生缺页中断的时候,会检查所有页面,根据RW位区分成4类:
- 1类、没有被访问,未被修改
- 2类、没有被访问,已被修改
- 3类、被访问了,未被修改
- 4类、被访问了,被修改
NRU(Not Recently Used)算法随机地从类编号最小的非空类中挑选一个页面淘汰。也就是从上面4个类中从第1类开始,如果第1类有页面那么就随机选择一个淘汰,如果第1类没有页面就顺次查找第2类。
RNU算法就是好理解并且好实现,就是效率不太高。
三、先进先出(FIFO)
FIFO(First-In First-Out)算法会维护一个链表。
最早进入内存的页会放到链表的表头上,最新进入内存的页会放到链表的尾部。缺页中断的时候,会从链表的表头开始淘汰。
缺点: 最早进入内存的不一定是不常用的页,没准也是经常使用的页,这个算法可能会把重要的经常使用的页淘汰出去。
四、第二次机会(second chance)
第二次机会页面替换算法是在先进先出页面替换算法的一次小改进。
第二次机会算法流程:
和先进先出一样,也是链表的表头放最早进入内存的页,链表尾放最新进入内存的页。但是检查的过程略有不一样,检查的时候从表头存的最早进入内存的页开始检查。
也是检查R位,如果 R 位为 0 表示这个页又老又没有被使用,所以直接淘汰这个页面就行了。
如果 R 位为 1 就把R位清零,然后把该页放到链表的尾部(相当于这个页刚进入内存一样),然后继续检查下一个老的页。
缺点: 经常要在链表上移动页页面,既降低了效率又不是很有必要。
五、时钟页面置换算法
页保存在一个类似表的环形链表中,一个表针指向最老的页面。发生缺页中断的时候判断R位,和第二次机会差不多,当 R 为 0 时淘汰页面,当 R 为 1 时清除R位并向前移动指针。
六、最近最少使用页面置换法(LRU)
LRU(Least Recently Used)的思想就是在前面几条指令中频繁使用的页面很可能在后面的几条指令中被使用,也就是说已经很久没使用的页面很有可能在未来一段时间不会被使用。
LRU算法流程:
也是维护一个链表,需要在内存中维护一个所有页面的链表,最近最多使用的页面在表头,最近最少使用的页面在表尾。非常麻烦的是,每次访问内存都要更新这个页面, 因为你访问了一个页就要从链表中更新这个页的状态,实现代价非常高。
七、NFU(最不常用)
NFU(Not Frequently Used)算法,将每个页面与一个软件计数器相关联,每次时钟中断将页面的R位(0或1)加到页面对应的软件计数器上,替换时找到计数器上值最小的页面淘汰。相当于跟踪了页面访问的频繁程度。
缺点; 不会忘记任何事。可能一段时间一个计数器的值非常高,但是后面一段时间这个页访问频率并不是很高,但是由于之前已经积累的值非常高,那么最后也不会淘汰该页。
八、老化算法
老化算法是对NFU算法做了一下修改:在R位被加之前,先将计数器向右移动一位,然后加到计数器的最左边的一个位。