一、最优页面置换算法
缺页中断发生时,需要调入新的页面而内存已满时,就需要选择内存当中哪个物理页面被置换。
目标:尽可能减少页面的换入换出次数(即缺页中断的次数),通常只能在局部性原理指导下依据过去的统计数据来进行预测。
页面锁定:用于描述必须常驻内存的操作系统的关键部分或时间关键(time-critical)的应用进程。实现方法是,在页表中添加锁定标志位(lock bit)。
一个好的置换算法的基本思路:缺页发生时,置换内存中未来最不常用的那个逻辑页面。
这种方式时无法实现的,因为操作系统没有办法知道未来会发生的情况,所以只能作为评判一个置换算法的依据。
二、先进先出算法
选择在内存驻留时间最长的页面并淘汰之。
Belady现象:增加缓存空间并不总是能够减少缺页错误的情况。在某些情况下,随着缓存空间的增加,缺页错误反而会增加(少数情况)
三、最近最久未使用算法(LRU)
如果需要查找的元素不存在栈中,就从栈底去除一个元素,并将需要的元素添加到栈顶。但是查询栈中是否存在开销太大。
四、时钟页面置换算法
页表中的标记位-访问位,每次访问后都会由硬件将这个标记为置为1(硬件加速)
循环扫描环形列表,并记录当前访问的位置,如果当前访问到访问位为0的(有一段时间没有被访问到的),那就先把访问页置1,然后将页替换出去。如果当前访问到1的那么就先把当前位置的访问位置为0,然后记录的位置向下挪一格,开始扫描环形列表,直到扫到访问位为0的项,将其对应的物理页面内容置换出去(这里肯定会找到访问位为0的,最差的情况是转一圈转到一开始置访问位为0的那个位置)
五、二次机会法
如果使用访问位,那么无法区分读和写(两者都是访问,会修改访问位)。所以需要同时使用标记位中的脏位来指导置换(脏位是只有修改才会置为1,同样也是由硬件修改,硬件加速)。目的就是减少对硬盘的写操作,因为如果脏位是0,也就是没有修改,那么说明内存中的内容和磁盘中的一致,不需要置换操作,直接丢弃即可。
如果访问位和dirty bit都是0,那么替换掉;如果其中一个是1,那么把这一位设置为0,指针往下走;如果都是1,那先把used换为0,说明有2次机会。
对于只读的页面会更快的被换出去,对于写过的页面会增加留在内存中的时间。
六、最不常用算法(LFU)
此方法没有考虑到时间的影响,如果一个程序在初始化时频繁调用某一段程序,初始化阶段过后不会调用此代码,那么之前调用频繁的代码就不会很快的替换出去。
所以我们可以通过没过一段时间就将访问次数减小的方式来把时间考虑进来。
七、对于Belady现象LRU,FIFO,Clock的比较
对于FIFO算法,会出现Belady现象。
LRU和Clock算法都拥有栈算法的特征所以不会发生Belady现象。
八、工作集模型
页面置换算法真正起到作用的前提是局部性原理,当进程的调用不符合局部性原理时,页面置换算法就起不到什么作用。
**工作集模型的目的:**证明局部性原理是成立的并对它进行定量分析
其实说白了就是看一段时间内所用到的逻辑页有哪些,根据这些逻辑页汇总集合来看是不是基本都靠在一起,以此来证明局部性原理。数据量越大那么得到的数据就越平稳,是一个趋势。
九、全局置换算法
工作集替换算法
随着时间的推进,工作集会持续移动,那么只要逻辑页不在工作集范围内,那么这个页就会被置出。而不是等到缺页异常发生的时候才进行置出操作。如果改页面是只读页面那么就是直接释放,如果不是则还需要写回到硬盘中去。可以在多个程序的环境中有效减少整体系统的缺页异常数量。
缺页率页面置换算法
通过缺页率来调整常驻集的大小:
对比:
- 全局页面置换算法不会等到有缺页异常发生的时候才去做出判断和对应的置出操作
- 局部置换算法只有等工作集满了之后或者发生了缺页异常才会去考虑置入置出操作
- 全局页面置换算法效果更好
十、抖动问题
花费大量的时间在处理缺页异常上,导致程序运行缓慢。
可以让操作系统根据CPU的利用率来调整平均页缺失时间使它和页缺失处理时间相等,或者提高内存的大小。以达到系统资源最佳利用的效果。