页面置换情景:

在系统运行过程中,若程序所要访问的页面不在内存而需要把他们调入内存,但内存已经没有空闲空间时,为了保证该进程能正常运行,系统必须从内存中调出一页程序或数据送到磁盘的交换区中,这个过程称为页面置换。决定将哪个页面调出,需根据一定的算法来确定,通常,把选择换出页面的算法成为页面置换算法。

常见的页面置换算法:

1.最佳页面置换算法

2.先进先出的页面置换算法(FIFO)

3.第二次机会页面置换算法(对FIFO的优化)

4.时钟页面置换算法(经常使用的页面置换算法之一)(又是对第二次机会的改进)

5.最近最少使用页面置换算法(LRU)(经常使用的页面置换算法之一)

1.最佳页面置换算法

该算法的基本思想是:

发生缺页时,有些页面在内存中,其中有一页将很快被访问(也就是下一条指令要访问的那一页),而其他页面则可能要到10、100或者1 000条指令后才会被访问,每个页面都可以用在该页面首次被访问前所要执行的指令数进行标记。 最佳页面置换算法规定:标记最大的页应该被置换。例如, 如果某页在800万条指令内不会被使用,另一页在600万条指令内不会被使用,则置换前一个页面。这个算法惟一的一个问题就是它无法实现,因为当缺页发生时,操作系统无法知道各个页面下一次是在什么时候被访问。

2.先进先出的页面置换算法

该算法的基本思想是:

总是淘汰在内存中停留得最久的那个页面。

具体实现方法:

是由操作系统维护一个所有当前在内存中的页面的链表,最新进入的页面放在表尾,最久进入的页面放在表头。当发生缺页中断时,淘汰表头页面并把新调入的页面加到表尾。FIFO页面置换算法容易理解和实现,但是其性能并不总是很好。

缺点:一些指令是在内存中必须是长时间的保留的,如果该使用FIFO算法,势必会造成不必要的开销。

3.第二次机会页面置换算法

算法思想介绍 :

它在FIFO的基础上增加了一个访问位,其性能较FIFO有了很大的提高,避免了把经常使用的页面置换出去。

实现:

和FIFO算法一样,操作系统维护一个所有当前在内存中的页面的链表,最新进入的页面放在表尾,最久进入的页面放在表头。

当需要置换页面是,检查最老页面的R位,如果它为0,表示它最近未被使用,也就是说,它又老又没用,可以立即置换。

如果是1,则把R位置为0,并把该页面放在链表尾端(即把它作为刚装入的页面一样),然后继续搜索。

名字由来:所访问位为1的不会马上被置换出去,而是将1置为0,添加到链表最末端,等到下次页面置换时才可能被置换出去,给了第二次的机会,所以叫第二次机会页面置换算法。

不足:第二次机会算法比较合理,但是效率较低,由于它经常需要在链表中移动页面,浪费时间。

4.时钟页面置换算法

改进:

时钟页面置换算法是对第二次机会算法的改进,也是现实中最常用的页面置换算法之一。

第二次机会算法比较合理,但是效率较低,由于它经常需要在链表中移动页面。

时钟页面置换算法改进了链表的组织方式。它将所有页面放置在一个类似钟面的环形链表中,用一个表针指向最老的页面。

实现:

当发生缺页中断时,算法首先检查表指针指向的页面,如果它的R位是0就淘汰该页面,并把置换进来的新的页面插入到这个位置,然后把表针前移一个位置。如果R位是1,那么清除R位并把表针前移一个位置。重复这个过程直到找到了一个R位为0的页面为止。

名字的由来:由于组织方式的链表像一个类似钟面的环形链表,和计时器没关系。

5.最近最少使用页面置换算法

LRU算法基于这样的原理:

在前面几条指令中频繁使用的页面很可能在后面几条指令中被使用。而已经很久没有使用的页面很有可能在未来较长的一段时间内仍然不会被使用。

LRU算法的主要问题是如何找出最近未被使用时间最长的页面: 硬件有一个64位的计数器C,它在每条指令执行完后自动加1。每个页表项中有一个足够容纳这个计数器值的域。在每次访问内存之后,将当前的C值保存到被访问页面的页表项中。发生缺页中断时,操作系统检查所有页表项中计数器的值,找到一个该值最小的页面,这个页面显然就是最近最少使用的页面。  

LRU的优点:

是性能很好,它提供了对最优页面置换算法很好的近似,并且它在理论上可以实现。

LRU算法的缺点:

在于它实际上实现很难。因为以上讨论的实现方式都需要硬件的参与,在现实中只有非常少的计算机拥有这种硬件。

页面置换算法可以分为两大类,全局置换和局部置换。

全局置换:允许一个进程从所有页帧集合中选择一个页帧置换,而不管该帧是否已经分配给其他进程,即一个进程可以从另一个进程中拿到帧。

局部置换:要求每个进程仅从自己的分配帧中进行选择。

页面抖动的产生:

由于置换算法的局限性,难免会有一些页面,被频繁的置换出置换进去,反反复复,无疑增大了系统的开销。

页面抖动的解决方案:

1.设计好的页面置换算法;

2.尽可能减少进程数量

3.增大内存