一 最优页面置换算法
在进程中,一个页面可能在10条,100条,n条指令后才可能使用,所以说指令越靠后,就可以先把它置换出去,但是这个是不可能是不可能实现的
因为程序在运行中你不可能知道以后的指令是啥,也不知道哪一条指令在什么时间出现,虽然实现不了但是可以作为我们设计页面置换算法的指导
二 最近为使用页面置换算法
系统为每一个页面设置了R位和M为,当页面被读到 时候设置R位,当页面被写的时候更新M位,一旦一个位被改变则它就保持到操作系统将它复位。
所以说最后每个页面会有四种状态:
0 没有被访问,没有被修改
1 没有被访问,但是被修改
2 被访问了,但是没有被修改
3被访问了,被修改了
每次发生页面中断的时候,操作系统都会检查每个页面的R和M位,淘汰一个没有被访问的已修改页面总比淘汰一个已访问的未修改页面要好。
三 先进先出算法FIFO
这个很好理解,最新进入的放在链表的尾部,最早进入的放在表头,表头的最先被淘汰
四 第二次机会页面置换算法
这个是FIFO的一种改进,再被淘汰的时候会检测页面的R位,如果说R位是1的话,将R为清零,然后将它放在表尾,就先刚放入一样。
五 时钟页面置换算法
第二次页面置换算法是一个比较合理的算法,但是这种算法要经常移动链表,降低了效率,所以说要使用一种环形链表,
当页面发生中断的时候,检查指针指向的页面的R位,如果说R位为0,则将该页面删除,并且添加一个新页面到这个位置,然后指针前移一个位置,
如果说R位为1 则将页面的R位置为0,然后将指针前移一位。
六 最近最少使用页面置换算法,
这种方法需要维护一个指针,最常使用的在表头,最近最少使用的在表尾,但是这种方法需要经常的更新链表,效率不高
六 工作集页面置换算法
在单纯的分页操作系统中,该开始的时候内存中是没有页面的,所以说每次读取叶框都会发生缺页中断,所以说这样的话会浪费大量的时间,
程序在运行过程中会发生一种情况就是在程序运行的某一阶段,程序只会访问页面中的一小部分。
一个进程中正在使用的页面的集合称为它的工作集,它的表示可以用w(k,t),就是在任意时刻t,前k次访问内存的页面的集合,也就是函数w(k,t)在t时刻工作集的大小
在多任务的系统中,有时候会把进程转移到磁盘上用以给其他进程腾出内存空间,如果说再次调入磁盘的时候就会发生大量的缺页中断,所以说不少系统都会跟踪程序的工作集,
让进程再次调入内存中的时候,它的工作集就已经在内存中,这种方式被称为预先调页。
如果说要实现工作集页面置换算法,则操作系统要跟踪哪些页面在工作集中,当发生页面中断的时候,淘汰一个不在工作集中的页面,为了实现该算法,就需要确定哪些页面在工作集中
比如说设置一个k位的寄存器,每次访问内存过后就把寄存器左移一位,然后然后在最右端插入刚才访问过的页面号,移位寄存器中的k个页面的页面号就是工作集中的内容,
每次发生缺页中断的时候就会访问移位寄存器中的内容并且排序,然后删除重复的页面,结果就是工作集,但是这种方式的开销太大,所以说基本上没有人使用这种方式,
作为替代可以不使用k次内存访问这个概念,转而定义工作集为过去T秒的时间内访问内存的集合
这个样的话就更容易实现。
下面就是基于工作集的页面置换算法
页表中至少包含两个域,上次使用该页面的时间以及R位
当发生缺页中断的的时间,就会扫描在内存中页面的R位如果说R位为1则说明该页面被访问过,所以说它肯定在工作集中,所以说它肯定不会被淘汰,
然后将R 为更改为1,将上次访问该页面的时间改为当前时间
如果说R为0,则该页面有可能会被置换,然后比较它的上次访问时间与T比较,如果说大于T则这个页面不在工作集中,所以说它就应该被置换,
如果小于0,那么该页面不应该被置换,但是应该记录下上次访问时间最靠前的那个页面,如果说扫描完整个页表都没有找到在工作集之外的页表项
则淘汰那个访问时间最靠前的页面
七 工作集时钟置换算法
当缺页中断发生的时候,需要扫描整个页表才能找到要被淘汰的页面,这样的话效率非常得低,
因此有一种改进算法,工作集时钟置换算法,这种算法把叶框放在一个循环链表中。