请求分页系统建立在基本分页系统基础之上,为了支持虚拟存储器功能而增加了请求调页功能和页面置换功能。请求分页是目前最常用的一种实现虚拟存储器的方法。
在请求分页系统中,只要求将当前需要的一部分页面装入内存,以便可以启动作业运行。在作业执行过程中,当所要访问的页面不在内存时,再通过调页功能将其调入,同时还可以通过置换功能将暂时不用的页面换出到外存上,以便腾出内存空间。
页面置换算法的主要目标是使页面置换频率最低(也可以说缺页率最低)。
常见的页面置换算法有以下几种:
1、最佳置换算法(Optimal,OPT)
2、先进先出页面置换算法(First In First Out,FIFO)
3、最近最久未使用( Least Recently Used,LRU)置换算法
4、第二次机会算法
5、时钟算法(clock)
6、改进时钟算法
7、最不常用算法(LFU,Least Frequently Used)
1、最佳置换算法(Optimal,OPT)
所选择的被换出的页面将是以后永不使用的,或者是在最长时间内不再被访问,通常可以保证获得最低的缺页率。但是由于人们无法预知一个页面多长时间不再被访问,因此该算法是一种理论上的算法。最佳置换算法可以用来评价其他算法。
举例:一个系统为某进程分配了三个物理块,并有如下页面引用序列:
开始运行时,先将 7, 0, 1 三个页面装入内存。当进程要访问页面 2 时,产生缺页中断,根据最佳置换算法,页面 7 在第18次访问才需要调入,再次被访问的时间最长,因此会将页面 7 换出,后面的过程以此类推,具体过程如下图;
2、先进先出页面置换算法(First In First Out,FIFO)
选择换出的页面是最先进入的页面。该算法实现简单,但会将那些经常被访问的页面也被换出,从而使缺页率升高。
举例:仍使用上面的例子,使用FIFO算法进行页面置换,过程如下:
进行了12次页面置换,比最佳置换算法正好多一倍。
FIFO算法还会产生 当分配的物理块数增大而页故障数不减反增的异常现象,称为Belady异常。FIFO算法可能出现Belady异常,而LRU和OPT算法永远不会。
3、最近最久未使用( Least Recently Used,LRU)置换算法
虽然无法知道将来要使用的页面情况,但是可以知道过去使用页面的情况。LRU 将最近最久未使用的页面换出,它认为过去一段时间内未使用的页面,在最近的将来也不会被访问。
实现方式一:
在内存中维护一个所有页面的链表。当一个页面被访问时,将这个页面移到链表表头。这样就能保证链表表尾的页面时最近最久未访问的。
实现方式二:
为每个页面设置一个访问字段,来记录页面自上次被访问以来所经历的时间,淘汰页面时选择现有页面中值最大的予以淘汰。
使用和上面同样的实例,采用LRU算法进行页面置换:
LRU性能较好,但需要寄存器和栈的硬件支持,LRU是堆栈类的算法,理论上可以证明,堆栈类算法不可能出现Belady异常,FIFO算法基于队列实现,不是堆栈类算法。
4、第二次机会算法
FIFO 算法可能会把经常使用的页面置换出去,为了避免这一问题,对该算法做一个简单的修改:
当页面被访问 (读或写) 时设置该页面的 R 位为 1。需要替换的时候,检查最老页面的 R 位。如果 R 位是 0,那么这个页面既老又没有被使用,可以立刻置换掉;如果是 1,就将 R 位清 0,并把该页面放到链表的尾端,修改它的装入时间使它就像刚装入的一样,然后继续从链表的头部开始搜索。
5、时钟算法(clock)
第二次机会算法需要在链表中移动页面,降低了效率。时钟算法使用环形链表将页面链接起来,再使用一个指针指向最老的页面。
最简单的时钟策略需要给每一页框关联一个附加位,称为使用位。当某一页首次装入内存中时,则将该页页框的使用位设置为1;当该页随后被访问到时(在访问产生缺页中断之后),它的使用位也会被设置为1。该方法中,用于置换的候选页框集合(当前进程:局部范围;整个内存;全局范围)被看做是一个循环缓冲区,并且有一个指针针与之相关联。当一页被置换时,该指针针被设置成指向缓冲区中的下一页框。当需要置换一页时,操作系统扫描缓冲区,以查找使用位被置为0的一页框。每当遇到一个使用位为1的页框时,操作系统就将该位重新置为0;如果在这个过程开始时,缓冲区中所有页框的使用位均为0时,则选择遇到的第一个页框置换;如果所有页框的使用位均为1时,则指针针在缓冲区中完整地循环一周,把所有使用位都置为0,并且停留在最初的位置上,置换该页框中的页。当需要使用的页已经存在时,则指针不会受到影响,不会发生转动。
可见该策略类似于FIFO(先进先出),唯一不同的是,在时钟策略中使用位为1的页框被跳过,该策略之所以称为时钟策略,是因为可以把页框形象地想象成在一个环中。许多操作系统都采用这种简单时钟策略的某种变体。
以下是一个使用实例,其中*号表示相应的使用位为1,红色单元格表示指针指向的位置
6、改进时钟算法
在页面中增加了修改位,1为修改过,0为未修改过。因为当发生缺页中断时,把未修改过的页面替换进外存就相当于把页面直接从内存中删除,因为内存和外存中所对应的该页面的内容相同,处理时间只有一次缺页中断访问外存的时间。而修改过的页面则还需要向外存中写入一次,再加上缺页中断的时间,相当于访问了两次外存,是上述未修改的两倍。所以避免把修改过的页面替换下去可以提高性能。
由访问位A和修改位M可以组合成下面四种类型的页面:
1类(A=0, M=0): 表示该页最近既未被访问, 又未被修改, 是最佳淘汰页。
2类(A=0, M=1): 表示该页最近未被访问, 但已被修改, 并不是很好的淘汰页。
3类(A=1, M=0): 最近已被访问, 但未被修改, 该页有可能再被访问。
4类(A=1, M=1): 最近已被访问且被修改, 该页可能再被访问。
可能有人会发现第2类这种情况根本不会出现,如果一个页帧被修改,其修改位会被置1,同时它也被使用了,其使用位也会被置1;即不会出现被修改但是没有被使用的情况。真实情况是,页帧的使用位可能会被清零,这样第3组经过一次清零就会变成第2组。
算法执行如下操作步骤:
从指针的当前位置开始,扫描帧缓冲区。在这次扫描过程中,对使用位不做任何修改。选择遇到的第一类页(A=0,M=0)作为淘汰页。
如果第1)步失败,则开始第二轮扫描,查找(A=0,M=1)的第二类页。选择遇到的第一个这样的页作为淘汰页。在这个扫描过程中,对所有经过的页,把它的访问位A设置成0。
如果第2)步失败,指针将回到它的最初位置,并且集合中所有页的访问位均为0。重复第1步,并且如果有必要,重复第2步。这样将可以找到被淘汰的页。
改进型的CLOCK算法优于简单CLOCK算法之处在于替换时首选没有变化的页。由于修改过的页在被替换之前必须写回,因而这样做会节省时间。
7、最不常用算法(LFU,Least Frequently Used)
是基于“如果一个数据在最近一段时间内使用次数很少,那么在将来一段时间内被使用的可能性也很小”的思路。
这种算法选择最近时期使用次数最少的页作为淘汰页。为每个页面配置一个计数器,一旦某页被访问,则将其计数器的值加1,在需要选择一页置换时,则将选择其计数器值最小的页面,即内存中访问次数最少的页面进行淘汰。
这种算法可能存在的问题是:有些也在进程开始时被访问的次数很多,但以后这些页可能不再被访问,这样的页不该长时间停留在内存中。解决这个问题的方法之一是定期的将计时器右移,以形成指数衰减的平均使用次数。
注意LFU和LRU算法的不同之处,LRU的淘汰规则是基于访问时间,而LFU是基于访问次数的。
————————————————
版权声明:本文为CSDN博主「qq_36132127」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_36132127/article/details/81126154