详解三种缓存过期策略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元素的位置即可。
下面附上三种算法的下载地址:
详解三种缓存过期策略LFU,FIFO,LRU(附带实现代码)的更多相关文章
- 详解三种java实现多线程的方式
java中实现多线程的方法有两种:继承Thread类和实现runnable接口. 1.继承Thread类,重写父类run()方法 ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
- Spring事务之详解--三种实现方式
实现购买股票案例: 一.引入JAR文件: 二.开始搭建分层架构---创建账户(Account)和股票(Stock)实体类 Account: /* * 账户 */ public class Accoun ...
- 缓存失效策略(FIFO,LRU,LFU)
当缓存需要被清理时(比如空间占用已经接近临界值了),需要使用某种淘汰算法来决定清理掉哪些数据.常用的淘汰算法有下面几种: 1. FIFO:First In First Out,先进先出.判断被存储的时 ...
- 详解GaussDB bufferpool缓存策略,这次彻底懂了!
摘要:华为云GaussDB(for mysql)是华为云自主研发的最新一代云原生数据库,采用计算存储分离.日志即数据的架构设计.具备极致可靠.极致性价比.多为扩展.完全可信等诸多特性. 一 .Gaus ...
- Python操作redis字符串(String)详解 (三)
# -*- coding: utf-8 -*- import redis #这个redis不能用,请根据自己的需要修改 r =redis.Redis(host=") 1.SET 命令用于设置 ...
- .NET4缓存过期策略摘录
以下是网上搜索的资料,仅供参考: 资料一:ASP.NET缓存中Cache过期的三种策略(转自51CTO) 我们在页面上添加三个按钮并双击按钮创建事件处理方法,三个按钮使用不同的过期策略添加ASP.NE ...
- asp.net的Context.Cache缓存过期策略
最近使用Context.Cache需要了解Cache的缓存过期策略. 文章:ASP.NET缓存中Cache过期的三种策略
- Redis详解(四)——删除策略
Redis详解(四)--删除策略 Redis中的数据特征 Redis是一种内存级数据库,所有数据均存放在内存中,内存中的数据可以通过TTL指令来获取其状态,当 key 不存在时,返回 -2 . 当 k ...
- 图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS)
参考网址:图文详解两种算法:深度优先遍历(DFS)和广度优先遍历(BFS) - 51CTO.COM 深度优先遍历(Depth First Search, 简称 DFS) 与广度优先遍历(Breath ...
随机推荐
- Oracle用户被锁原因及办法
Oracle用户被锁原因及办法 在登陆时被告知test用户被锁 1.用dba角色的用户登陆,进行解锁,先设置具体时间格式,以便查看具体时间 SQL> alter session set nl ...
- iOS学习笔记——滚动视图(scrollView)
滚动视图:在根视图中添加UIScrollViewDelegate协议,声明一些对象属性 @interface BoViewController : UIViewController<UIScro ...
- ef
现阶段使用回溯 entityframework作为.net平台自己的一个orm的框架,之前在项目中也有使用,主要采用了table和model first的方式,此两种感觉使用上也是大同小异.在项目中经 ...
- 阅读微信支付demo收获
1,公司现有系统有很多,存放重要接口的日志分布在不同的库,每个系统都有单独的日志采集表,日志采集模块: ???? 这些日志可以统一放到一个地方,通过一个组件提供出去 ...
- 【Java每日一题】20161226
package Dec2016; public class Ques1226 { static{ num = 1; } public static int num = 2; public static ...
- python之最强王者(6)——列表(List)
1.Python 列表(List) 序列是Python中最基本的数据结构.序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推. Python有6个序列的内置 ...
- Spring+SpringMVC+Hibernate简单整合(转)
SpringMVC又一个漂亮的web框架,他与Struts2并驾齐驱,Struts出世早而占据了一定优势,下面同样做一个简单的应用实例,介绍SpringMVC的基本用法,接下来的博客也将梳理一下Str ...
- 怎样给div增加resize事件
当浏览器窗口被调整到一个新的高度或宽度时,就会触发resize事件,这个事件在window上面触发,那么如何给div元素增加resize事件,监听div的高度或宽度的改变呢? 先来回答另一个问题,监听 ...
- MapFile生成WMS
MAP NAME "HBWMS" STATUS ON SIZE 800 600 EXTENT 107.795 28.559 116.977 33.627 UNITS ME ...
- NSURLConnection实现文件上传和AFNetworking实现文件上传
请求的步骤分为4步 1.创建请求 2.设置请求头(告诉服务器这是一个文件上传的请求) 3.设置请求体 4.发送请求 NSURLConnection实现文件上传 // 1.创建请求 NSURL *url ...