内存管理笔记八、页面更换算法

引言:第七篇内存管理笔记,有介绍到分页的内存管理。其克服了外部碎片、程序不能大于物理内存等缺点。本篇笔记将简单介绍常见的页面更换算法思想。


一、页面需更换的原因

  在交换系统下,一个程序作为一个整体加载到内存。因此,在运行时,无需从磁盘上加载任何东西。而分页系统下,一个程序的所有页面并不一定都在内存中,因此,在执行的过程中有可能发生页面不在内存的情况。
  如果访问的页面不在内存中,则系统将产生缺页中断。缺页中断服务将负责把磁盘上的数据加载到物理内存中来。如果物理内存还有空闲空间,那就直接使用空闲的页面。但如果空闲页面已满,则需要挑选某个已经使用过的页面进行替换。


二、页面更换期待达到的目标

  如果挑选的页面是之后很快又要被访问的页面,那么系统将很快再次产生缺页中断。因为磁盘的访问速度远远低于内存的访问速度,缺页中断的代价是非常巨大的。因此,挑选哪个页面进行更换是有要求的
  页面更换时挑选页面的目标是什么呢?当然还降低随后发生缺页中断的次数或者频率。因此,我们选择的页面应当是随后相当长时间内不会被访问的页面。


三、常见算法的思想

3.1、随机更换算法

  最不负责任的算法是随机更换算法,在需要更换页面的时候,产生一个随机页面号,而替换与该页面号对应的物理页面号。这种算法计算需要替换页面号时速度很快,但是难以最小化随后缺页中断次数。

3.2、先进先出算法(FIFO)

  先进先出的实现机制是使用链表将所有在内存的页面按照进入时间的早晚,链接起来,然后每次置换链表头上的页面就行了,新加进来的页面则挂在链表的末端。在下图1中,如果下次需要寻找页面来替换,A将成为替换页面。

内存管理笔记八、页面置换算法
图1、按照进入内存早晚构建的页面链表

  FIFO的优点是易于实现,但这个绝对公平的算法容易降低效率。例如先加载进来的页面是经常被访问的页面,这样很可能将使用频次高的页面替换到磁盘上,导致很快发生缺页中断。

3.3、第二次机会算法

  由于FIFO只考虑进入内存的时间,不关系一个页面被访问的频率,从而有可能造成替换掉一个经常访问的页面而造成效率低下。那么我们对FIFO进行改进的方向就是考虑一个页面是否经常被访问。
  改进的手段就是在使用FIFO更换一个页面时,需要看一下该页面是否在最近被访问过。若没有访问则替换,若被访问过(通过查看其访问位的内存)则不替换,并且将该页面挂到链表末端,并将该页面进入内存时间设置为当前时间,并将其访问位清零,这样,相当于给最近访问过的页面第二次机会

内存管理笔记八、页面置换算法
图2、A获得第二次机会,链表格局变化

3.4、时钟算法

  第二次机会算法简单、公平、易于实现。但是每次给予一个页面第二次机会时,将其转移到链表末端要耗费时间。另外每次访问位要在页面替换时进行扫描才可能清零,其时间局域性不好,访问位为1的页面可能是很久以前访问的,其时间分辨粒度低。基于这些缺点,人们想出了时钟算法。

  在时钟算法中,将页面排成一个始终的形状(逻辑)。每次在更换页面时,从时钟指向的页面开始检查,如果当前页面的访问位为0,即从上次检查到这次,该页面没有访问过,将该页面替换。如果当前页面被访问过,将其访问位清0,并顺时针移动至下一个页面,直到找到一个访问位为0的页面。

内存管理笔记八、页面置换算法
图3、时钟算法示意图

  第二次机会算法使用的数据结构是链表,这里使用的是索引(整数指针)。时钟算法不需要额外的空间,更大的好处是页面访问位会定期清零,使得时钟算法的时间分辨粒度较第二次算法更高,从而获得更好的页面替换效果。

3.5、最优更换算法

  前面介绍的四种算法,没有将替换页面与其访问频次挂钩,我们这样很难选出一个在今后很长时间内不会访问的页面。因此,需要对页面的个体特性进行考虑,对不同访问频次的页面区分对待。
  最理想的页面替换算法是选择一个再也不会被访问的页面进行替换,如果不存在这样的页面,那至少选择一个在随后最长时间不会被访问的页面,保证随后发生缺页中断的次数最小。

3.5、最近未使用(Not Recently Used, NRU)算法

  NRU就是选择一个最近一段时间内,没有访问过的页面进行替换,作出这种选择是基于程序访问的时空局域性。依据时空局域性,一个最近没有访问过的页面,在随后的时间内也不太可能被访问,而NRU的实现就是利用页面的访问和修改位。在下图四种类型中,依次选择。

内存管理笔记八、页面置换算法
图4、按照访问位和修改位取值将页面分为4类

对第二种状态的解释,为什么访问位为0,而修改位为1:因为操作系统会定期对访问位清0,而修改位不会。

3.6、LRU(Least Recently Used, LRU)算法

  简单讲,其是NRU的改进,不仅仅考虑最近是否使用,而且考虑最近使用的频率。
  LRU算法的实现必须以某种方式记录每个页面被访问的次数,简单的办法就是在页表的记录项里面增加一个计数域,一个页面被访问一次,则这个计数器的值加1。当然还有很多方式实现,LRU,这里不作为重点。

3.7、工作集群算法

  考虑到LRU算法实现,其需要对每个页面保持某种记录,并在每次页面访问时或周期性对这些记录更新,造成时间空间成本高。工作集概念来源于程序访问的时空局域性,在一段时间内,程序访问的页面将局限在一组页面集合上。
  例如,最近K次访问均发生在某m个页面上,那么m就是参数为k时的工作集。用w(k, t)表示时间t时k次访问所涉及的页面数量。显然随着k的增长,w(k, t)的值将随之增长,在k增长至某个数值后,w(k, t)值增长将及其缓慢甚至接近停滞,并维持一段时间。

内存管理笔记八、页面置换算法
图5、工作集与最近访问次数的关系

  因此我们的目标就是维持当前的工作集的页面在物理内存里面。其优点是实现简单,空间成本低,且时间成本不大。其实现机制这里不作为重点。

小结:本篇文章讲了页面切换产生的原因,其追求的目标,及常用的几种算法。有一个困惑,就是linux下如何查看当前系统的页面置换算法?

参考资料:
《操作系统之哲学原理》 邹恒明著

纠错与建议
邮箱:[email protected]


相关文章:

  • 2021-10-09
  • 2021-09-27
  • 2022-12-23
  • 2022-12-23
  • 2021-10-09
  • 2021-07-06
  • 2021-07-10
  • 2022-02-09
猜你喜欢
  • 2021-08-10
  • 2022-12-23
  • 2021-05-11
  • 2021-08-15
  • 2021-05-17
  • 2021-11-22
相关资源
相似解决方案