在进程运行的过程中,在调入时,若内存中没有空闲空间,那么为了所需要的页面能调入,必须选择一些页调出。算法的好坏直接印象系统的性能,不适当的算法可能引起系统的抖动(至于什么叫抖动,下篇再说)。
选择算法的出发现在于:把未来不再使用的或者是短期内不再使用的页调出。但是由于未来不可预估,因此只能根据过去的数据进行预测。
那么怎么进行相应的预测呢?假设分配给进程的存储块数量为3.而进程在执行的过程中需要访问5个页面,运行的时候,产生的地址流为 2 3 2 1 5 2 4 5 3 2 5 2,也就是说进程访问的第一个页为2,第二个页为3,最后一页为2。将2 3 1 装入存储块以后,访问5的时候,便会发生缺页,于是调用相应的页面置换算法。
最佳置换法(OPT)
该算法要求选择那些不再使用或者最长时间不再使用的页,由于无法预知内存中哪些页不再使用,或者最长时间不再使用,因此该算法是无法实现的 ,但是可以作为其他算法的参考标准。
同样我们假设分配了3个存储块,访问的页地址流如下,根据OPT算法,过程如下:
先进先出算法FIFO
算法:总是淘汰最先进入内存的页(即在内存时间中待得最久)。
这里注意一个点,缺页不等于置换,比如前三次的缺页,只是单独的没有页面在内存块,只有调入,没有换出。
所以,缺页率为9/12, x 100% = 75%。
最近最久未使用算法LRU
FIFO之所以性能较差,是因为各个页调入内存的时间,并不能反映,页面的使用情况,最近最久未使用算法,以过去预测未来,每个页面上的访问字段,记录了页面上子上次未被访问所经历的时间T,淘汰的时候,选择T值最大的页。
从做法上看,就是从要置换的页往前看,看谁离它最远,这种算法与OPT算法接近,但是由于增加了新的字段,操作系统的开销比较大。
时钟置换算法(clock算法)
尽管LRU算法与OPT算法接近,但是实现起来较为困难,因此在实际的应用中,大多采用LRU的近似算法,clock算法(也称NRU算法)。
该算法在页表中设置访问字段A和修改位M,将内存中的所有页面用指针链接成一个循环队列,当页面被访问的时候,其访问位置为1,系统置换的时候,检查每页的访问页位,为0的时候淘汰,为1的时候重置为0.接着继续查找其他页,直到访问页为0的页。
在内存中,如果一个页被修改过,则需要将它重新写回磁盘,因此,淘汰修改过后的页面所付出的开销要比未修改过的页面大。(因此,一般不淘汰修改后的页面)
所以,A和M有四种可能:
- A = 0,M = 0. 最近未被访问,也没有被修改(是最佳的置换页面)
- A = 0,M = 1.最近未被访问,但是被修改过
- A = 1,M = 0.最近被访问过,但是未被修改
- A = 1,M = 1.最近被访问过,也被修改过(所以该页很可能再次被访问)
具体的做法:
(1).从指针所指的位置,扫描循环队列,找的是 A = 0,M = 0的页,遇到便淘汰。第一次扫描期间不改变其访问位
(2).若(1)失败,那么找 A = 0,M = 1的页面,遇到则淘汰,第二次扫描期间,所经历的页,访问位修改为0.
(3).重复(1)(2),此时一定能找到 A = 0,M = 0的页面