计算机的内存相对于硬盘来说是极为稀缺空间资源,因此更容易出现容量上限的问题。当内存的空间满了时并不是说就爆了,操作系统会机智地借用硬盘来暂存某些内存中的数据(详见313的虚拟内存)。内存里的基本存储单位为byte,但是一般并不会一个一个转移,而是会将内存空间化为一个一个的页(page),然后一个页一个页的转移。那么什么样的内存页会被优先转存到硬盘里呢?存在时间最长的?利用率最低的?此时用来决定的算法便被称为置换算法。
一般会见到的置换算法有LRU(Least Recently Used),MRU(Most Recently Used),FIFO(First In First Out)等等,而时钟(Clock)置换算法(又名Second Chance Algorithm)是其中一种算是比较折中的算法,实现起来相对简单。为什么叫时钟呢?因为这个算法在置换时会逐个检查每个frame,就像时钟的轮询一样。这里先定义一下几个term,也可以称他们为buffer的状态:
- buffer pool:frame的集合,即某一块内存空间。
- frame/buffer:内存的空槽,每个大小为一个page,初始时为空,即不存任何内存页。
- 页缺(Page Fault):每当想要用到的内存页不在任何frame中时即被认为是一次页缺,也就是会出现置换的时刻。
- Reference/Dirty Bit:每个frame都会有一个bit来记录它的一个二元状态,为1时即此内存页刚刚被访问过,此时此页不会被置换;为0时即为一种可以置换的状态。
- 最旧的页:最近的还没有被置换的页,用来追踪上一个置换的位置,即指向每次被置换的frame的下一个frame
算法的流程可以简单地归纳为几个状态下的置换规则:
- 如果任何frame中已存在要访问的内存页,则此时不会出现页缺,buffer pool的状态不会有任何改变。
- 如果任何frame中都不存在要访问的页,则出现页缺,需要从最旧的页开始循环来找到可替换的frame,此时buffer的状态一定改变。
- 在循环中,如果当前frame的bit为0,则直接替换为要访问的内存页,并将bit设为一,然后将最旧的页设为此frame的下一个frame。
- 在循环中,如果当前frame的bit为1,则将bit设成0,然后去往下一个frame。(给他第二次机会)
这个算法还有另一个版本,但我觉得比这种要麻烦,例子就不举了,Google一个吧。