时钟策略是一种在操作系统中的概念,它是一种置换策略,它可以以很小的开销来接近LRU(Least Recently Used,最近最少使用)的功能。理解了时钟策略以后,发现它的思想很简单又很强大,将来可能可以用在其他领域,故记录之。
使用场景
要加载的页面没有内存空间存放,需要在已加载到内存的页中选择一个“牺牲者”,腾出内存空间,以便加载请求的页面。且不希望选择最近使用过的页作为“牺牲者”(因为它有可能马上又要被访问)。
页面是数据,内存空间是容器。
时钟策略的思想
-
对于每一个在内存中的页,维护一个位,表示是否最近使用过(0代表最近没有使用过,1代表最近使用过)。所有“使用”位组成一个循环数组,像“钟上的数字”。再使用一个指针,用来检查它指向的使用位是0还是1(是否最近使用过)。
- 页加载到内存中的时候,将使用位置为1。
- 页中的数据被访问的时候,也将使用位置为1。
- 需要寻找牺牲者的时候,检查指针指向的使用位是否为0:
- 如果为0,代表这一页最近没有被使用,则将这个使用位对应的页作为“牺牲者”。
- 如果为1,代表这一页最近被使用,不能将它作为牺牲者。先将这个使用位置为0,然后将指针指向下一个使用位,重复第4步。
为什么检索发现使用位为1后,要将它置为0呢?因为使用位为1的意义是,页在上一轮被访问过。当指针经过这个使用位以后,新的一轮开始了,自然就应该将它标识为“这一轮未被访问过”。
我对使用位的理解
我将使用位理解为“容忍度”。
- 容忍度为1代表能够忍受这一页继续留在内存中
- 容忍度为0代表忍受已经达到极限,不能在将这一页继续留在内存中。
请想象操作系统拥有人的情绪:
- 页面刚刚加载到内存中,操作系统对“新鲜事物”有1忍受度。
- 页中的数据被访问,操作系统想:这一页还是挺有用的嘛,忍受它1轮吧。
- 寻找牺牲者时,检查指针指向的使用位是否为0:
- 使用位为1,操作系统想:你上一轮起到了作用,我这次先放过你,但是下一次就不一定了,我要看你在新一轮的表现怎么样。
- 使用位为0,操作系统想:我对你的忍受度已经达到极限了,上一轮你什么都没有做!你回磁盘去吧,给新的页腾出位置!
有很多置换策略都是时钟策略的变体(见参考资料的维基百科),理解了时钟策略才能理解那些更具体的算法。