页面置换算法:
当缺页中断发生时,需要调入新的页面而内存已满时,闲着物理内存中哪一个物理页面置换,尽可能的减少页面的换进换出(即缺页中断次数),实现页面锁定(常驻内存)
- 局部页面置换算法
- 全局页面置换算法
局部页面置换算法:
-
最优页面置换算法:当发生缺页中断时,对于保存在物理内存中的每一个逻辑页面,计算下一次访问之前还需等待多长时间,从中选择时间最长的,作为被置换的页(理想情况,可以作为评判其他置换算法的依据)
-
先进先出算法FIFO:选择内存中驻留时间最长的并淘汰之,如果页面已存在则直接访问不会对其进行移动操作。
实现简单性能较差
,很少单独使用,调出的页面有可能是经常要访问的页面,并且有Belady现象,给程序物理页帧越多发生缺页次数越多
-
最近最久未使用算法LRU:
开销较大
当发生缺页中断时,选择最久未使用的那个页面。这是对未来的预测
算法实现
-
由系统维护一个链表,当访问内存时将其移到链表头,不存在物理页时直接加到链表头,发生缺页中断时淘汰链表末尾的页面
-
通过页面活动栈,当访问某页将其插入到栈顶,然后搜索栈内是否存在相同页号,若有将其抽出。选择栈底页面淘汰
-
时钟页面置换算法:
LRU的近似,对FIFO的改进
,访问内存后硬件自动将access bit置为1,对所有页抽象成一个环,指针首先指向第一位,当发生缺页中断时判断access bit,为1的话将其置为0并将指针指向下一位,目的是让刚才的页“老”一点,直到access bit为0的位将其替换,将access bit置为1。内存中存在不需要替换时将access bit置1,指针位置不动
-
二次机会算法:尽量使经常读写的页保留在内存中,其次使经常读的页保存在内存中,优先替换未经常使用和修改位(dirty bit)为0的页,淘汰时同时考虑两个位,替换规则如下:
模拟:
- 最不常用算法LFU:当发生缺页中断时,淘汰访问次数最少的页面。
存在的问题:当一个页面开始时访问次数比较多,后期就不访问了,比如程序初始化;实现比较麻烦
解决方法:定期将次数寄存器右移一位(即除2)
局部替换算法总结
Belady现象:
在采用FIFO算法时,有时会出现分配的物理页面数增加,缺页率反而提高的异常现象
Belady现象的原因:
该算法置换目标是与程序动态访问特征是矛盾的,他置换出的页面不一定是进程不会访问的,对已存在的页面访问时不会将其换到栈顶,因为FIFO不会记录访问次数,只会记录存在最久的页面
- 例子:
分配页面数为3,产生9次缺页中断
分配页面数为4,产生10次缺页中断
使用LRU算法不会产生Belady现象
LRU、FIFO、Clock算法的对比:
LRU算法和FIFO本质上都是先进先出的思路,只不过LRU是针对页面的最近访问时间来进行排序,所以需要在每一次页面访问的时候动态地
调整
各个页面之间的先后顺序(有一个页面的最近访问时间变了) ;
而FIFO是针对页面进入内存的时间来进行排序,这个时间是固定不变
的,所以各页面之间的先后顺序是固定的。如果一个页面在进入内存后没有被访问,那么它的最近访问时间就是它进入内存的时间。
换句话说,如果内存当中的所有页面都未曾访问过,那么LRU算法就退化为FIFO算法。因此除了和算法有关,还和程序本身有关(局部性)。
Clock算法是对LRU算法的近似,只用一个access bit或access + dirty两个bit记录访问时间LRU算法性能较好,但系统开销较大; FIFO算法系统开销较小,但可能会发生Belady现象。因此,折衷的办法就是Clock算法,在每一次页面访问时,它不必去动态地调整该页面在链表当中的顺序,而仅仅是做一个标记,然后等到发生缺页中断的时候,再把它移动到链表末尾。对于内存当中那些未被访问的页面,Clock算法的表现和LRU算法一样好; 而对于那些曾经被访问过的页面,它不能象LRU算法那样,记住它们的准确位置。
工作集模型:
- 常驻集:
工作集不一定都在物理内存中
全局页面置换算法
不同的程序提供不同的常驻集使整体缺页中断数少,可以提高性能,往往局部页面置换算法不能满足要求,因此需要全局页面置换算法
一旦不在工作集内就将其换出物理内存,无论是否发生缺页中断
缺页率页面置换算法PFF
可变的分配策略,依据是缺页的频度
缺页率:
缺页次数 / 内存访问次数
或 缺页的平均时间间隔的倒数
影响因素:
- 页面置换算法
- 分配给进程的物理页面数目
- 页面本身的大小
- 程序编写的方法
算法实现:
- 当缺页率高的时候,增加工作集
- 当缺页率低的时候,减少工作集
-
例子:
-
与工作集置换算法不一样:
对页的调整的时机是不同的,工作集置换算法在内一次访问内存时都判断是否处于工作集内,不在的话清除之,而给予缺页率的置换算法只在产生缺页中断时判断
抖动问题:
- 如果分配给一个进程的物理页面太少,不能包含整个的工作集,即常驻集小于工作集,那么进程将会造成很多的缺页中断,需要频繁地在内存与外存之间替换页面,从而使进程的运行速度变得很慢,我们把这种状态称为“抖动”。
- 产生抖动的原因:随着驻留内存的进程数目增加,分配给每个进程的物理页面数不断减小,缺页率不断上升。所以OS要选择一个适当的进程数目和进程需要的帧数,以便在并发水平和缺页率之间达到一个平衡。
只有一个程序占用大量内存也会产生抖动现象