zoukankan      html  css  js  c++  java
  • 详解三种缓存过期策略LFU,FIFO,LRU(附带实现代码)

      在学操作系统的时候,就会接触到缓存调度算法,缓存页面调度算法:先分配一定的页面空间,使用页面的时候首先去查询空间是否有该页面的缓存,如果有的话直接拿出来,如果没有的话先查询,如果页面空间没有满的时候,使用新页面的时候,就释放旧的页面空间,把新页面缓存起来,以便下次使用同样的页面的时候方便调用。

    缓存调度流程图

    缓存机制就是上面所说的那样,但是实现的过程以及淘汰旧页面的机制不同,所以会有不同缓存调度方法,就常见的就是FIFO,LRU,LFU缓存过期策略。

    1.FIFO(First In First out):先见先出,淘汰最先近来的页面,新进来的页面最迟被淘汰,完全符合队列。

    2.LRU(Least recently used):最近最少使用,淘汰最近不使用的页面

    3.LFU(Least frequently used): 最近使用次数最少, 淘汰使用次数最少的页面

    下面详细解释三种算法是怎么实现的。下面解释转自http://blog.csdn.net/yangpl_tale/article/details/44998423

     一、FIFO

    按照“先进先出(First In,First Out)”的原理淘汰数据,正好符合队列的特性,数据结构上使用队列Queue来实现。

    如下图:

    1. 新访问的数据插入FIFO队列尾部,数据在FIFO队列中顺序移动;

    2. 淘汰FIFO队列头部的数据;

    二、LRU

    (Least recently used,最近最少使用)算法根据数据的历史访问记录来进行淘汰数据,其核心思想是“如果数据最近被访问过,那么将来被访问的几率也更高”。

    最常见的实现是使用一个链表保存缓存数据,详细算法实现如下:

    1. 新数据插入到链表头部;

    2. 每当缓存命中(即缓存数据被访问),则将数据移到链表头部;

    3. 当链表满的时候,将链表尾部的数据丢弃。

    三、LFU

    (Least Frequently Used)算法根据数据的历史访问频率来淘汰数据,其核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”。

    LFU的每个数据块都有一个引用计数,所有数据块按照引用计数排序,具有相同引用计数的数据块则按照时间排序。

    具体实现如下:

    1. 新加入数据插入到队列尾部(因为引用计数为1);

    2. 队列中的数据被访问后,引用计数增加,队列重新排序;

    3. 当需要淘汰数据时,将已经排序的列表最后的数据块删除。

     前面两种算法实现并不算难,LFU实现起来会有点麻烦,下面是我自己考虑的淘汰实现思路,来了页面的时候会发生如下情况

    1.判断是否有旧的页面存在,没有则淘汰尾部元素,增加新的元素。

    2.有旧页面的存在,查询旧页面的位置,然后把旧页面的元素一直上移到同等次数的页面的上一个元素。

    比如说元素(a,1)代表页面为a,调用次数为1,那么在缓存里面集合为{ (f,4), (e,2), (d,2),  (c,2), (b,2), (a,1) },这时候调用c页面,只需要用折半查询找到c元素的位置,把c元素存储起来,把c元素到e元素之间的元素(不包含c元素)全部后移一位,然后把c元素放到原来e元素的位置即可。

    下面附上三种算法的下载地址:

    下载地址

  • 相关阅读:
    treeview(树加载)
    9.SQL存储过程实例详解
    面向对象之封装
    cookie和session
    自定义web框架
    IO多路复用
    协程
    concurrent.futures模块(进程池/线程池)
    死锁与递归锁及信号量等
    并发编程之多线程
  • 原文地址:https://www.cnblogs.com/s-b-b/p/6047954.html
Copyright © 2011-2022 走看看