缓存算法(FIFO 、LRU、LFU三种算法的区别)
FIFO算法
FIFO 算法是一种比较容易实现的算法。它的思想是先进先出(FIFO,队列),这是最简单、最公平的一种思想,即如果一个数据是最先进入的,那么可以认为在将来它被访问的可能性很小。空间满的时候,最先进入的数据会被最早置换(淘汰)掉。
FIFO 算法的描述:设计一种缓存结构,该结构在构造时确定大小,假设大小为 K,并有两个功能:
- set(key,value):将记录(key,value)插入该结构。当缓存满时,将最先进入缓存的数据置换掉。
- get(key):返回key对应的value值。
实现:维护一个FIFO队列,按照时间顺序将各数据(已分配页面)链接起来组成队列,并将置换指针指向队列的队首。再进行置换时,只需把置换指针所指的数据(页面)顺次换出,并把新加入的数据插到队尾即可。
缺点:判断一个页面置换算法优劣的指标就是缺页率,而FIFO算法的一个显著的缺点是,在某些特定的时刻,缺页率反而会随着分配页面的增加而增加,这称为Belady现象。产生Belady现象现象的原因是,FIFO置换算法与进程访问内存的动态特征是不相容的,被置换的内存页面往往是被频繁访问的,或者没有给进程分配足够的页面,因此FIFO算法会使一些页面频繁地被替换和重新申请内存,从而导致缺页率增加。因此,现在不再使用FIFO算法。
LRU算法
LRU(The Least Recently Used,最近最久未使用算法)是一种常见的缓存算法,在很多分布式缓存系统(如Redis, Memcached)中都有广泛使用。
LRU算法的思想是:如果一个数据在最近一段时间没有被访问到,那么可以认为在将来它被访问的可能性也很小。因此,当空间满时,最久没有访问的数据最先被置换(淘汰)。
LRU算法的描述: 设计一种缓存结构,该结构在构造时确定大小,假设大小为 K,并有两个功能:
- set(key,value):将记录(key,value)插入该结构。当缓存满时,将最久未使用的数据置换掉。
- get(key):返回key对应的value值。
实现:最朴素的思想就是用数组+时间戳的方式,不过这样做效率较低。因此,我们可以用双向链表(LinkedList)+哈希表(HashMap)实现(链表用来表示位置,哈希表用来存储和查找),在Java里有对应的数据结构LinkedHashMap。
LInkedHashMap
利用Java
的LinkedHashMap
用非常简单的代码来实现基于LRU算法的Cache功能
import java.util.LinkedHashMap;
import java.util.Map;
/*** 简单用LinkedHashMap来实现的LRU算法的缓存*/
public class LRUCache<K, V> extends LinkedHashMap<K, V> {private int cacheSize;public LRUCache(int cacheSize) {super(16, (float) 0.75, true);this.cacheSize = cacheSize;}protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {return size() > cacheSize;}
}
测试:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;public class LRUCacheTest {private static final Logger log = LoggerFactory.getLogger(LRUCacheTest.class);private static LRUCache<String, Integer> cache = new LRUCache<>(10);public static void main(String[] args) {for (int i = 0; i < 10; i++) {cache.put("k" + i, i);}log.info("all cache :'{}'",cache);cache.get("k3");log.info("get k3 :'{}'", cache);cache.get("k4");log.info("get k4 :'{}'", cache);cache.get("k4");log.info("get k4 :'{}'", cache);cache.put("k" + 10, 10);log.info("After running the LRU algorithm cache :'{}'", cache);}
}
Output:
all cache :'{k0=0, k1=1, k2=2, k3=3, k4=4, k5=5, k6=6, k7=7, k8=8, k9=9}'
get k3 :'{k0=0, k1=1, k2=2, k4=4, k5=5, k6=6, k7=7, k8=8, k9=9, k3=3}'
get k4 :'{k0=0, k1=1, k2=2, k5=5, k6=6, k7=7, k8=8, k9=9, k3=3, k4=4}'
get k4 :'{k0=0, k1=1, k2=2, k5=5, k6=6, k7=7, k8=8, k9=9, k3=3, k4=4}'
After running the LRU algorithm cache :'{k1=1, k2=2, k5=5, k6=6, k7=7, k8=8, k9=9, k3=3, k4=4, k10=10}'
LFU算法
LFU(Least Frequently Used ,最近最少使用算法)也是一种常见的缓存算法。
顾名思义,LFU算法的思想是:如果一个数据在最近一段时间很少被访问到,那么可以认为在将来它被访问的可能性也很小。因此,当空间满时,最小频率访问的数据最先被淘汰。
LFU 算法的描述:
设计一种缓存结构,该结构在构造时确定大小,假设大小为 K,并有两个功能:
- set(key,value):将记录(key,value)插入该结构。当缓存满时,将访问频率最低的数据置换掉。
- get(key):返回key对应的value值。
算法实现策略:考虑到 LFU 会淘汰访问频率最小的数据,我们需要一种合适的方法按大小顺序维护数据访问的频率。LFU 算法本质上可以看做是一个 top K 问题(K = 1),即选出频率最小的元素,因此我们很容易想到可以用二项堆来选择频率最小的元素,这样的实现比较高效。最终实现策略为小顶堆+哈希表。
缓存算法(FIFO 、LRU、LFU三种算法的区别)相关推荐
- java中奖率算法_抽奖概率-三种算法
一.逢"几"中奖 逢"几"中奖,即通过预估抽奖人数和奖品数来判断,"几"=(抽奖人数/奖品数)*N.这是一种最简单抽奖算法,适合抽奖人数众多 ...
- 绘制云图的三种算法(附C#代码)
我们要做什么呢?就是输入一个二维数组, TestData = new double[9, 6] {{ 26,28,29,32,28,27},{ 27,30,32,35,30,28},{ 24,27,3 ...
- AES,RSA,IBE三种算法的比较
文章目录 三种算法的概念解释 三种算法各自的优略 三种加密算法的对比 三种算法的应用场景 三种算法的概念解释 AES: 最为常见的一种对称加密算法,对称式加密就是加密和解密使用同一个密钥.信息接收双方 ...
- 爱因斯坦谜题解答(三种算法比较)
爱因斯坦谜题: 在一条街上有颜色互不相同的五栋房子,不同国籍的人分别住在这五栋房子力,每人抽不同品牌的香烟,喝不同的饮料,养不同的宠物.已知如下情况: 1. 英国人住红色房子里. 2. 瑞 ...
- EL之DTRFGBT:基于三种算法(DT、RF、GBT)对泰坦尼克号乘客数据集进行二分类(是否获救)预测并对比各自性能
EL之DT&RF&GBT:基于三种算法(DT.RF.GBT)对泰坦尼克号乘客数据集进行二分类(是否获救)预测并对比各自性能 目录 输出结果 设计思路 核心代码 输出结果 设计思路 核 ...
- LVS三种模式的区别及负载均衡算法
转载自 LVS三种模式的区别及负载均衡算法 LVS简介 LVS(Linux Virtual Server)即Linux虚拟服务器,是一个虚拟的服务器集群系统,由章文嵩博士在1998年5月成立,在li ...
- java 求最大公因数_求最大公约数的三种算法(java实现)
三种算法: //欧几里得算法(辗转相除): public static int gcd(int m,int n) { if(m int k=m; m=n; n=k; } //if(m%n!=0) { ...
- SQL Server 索引基础知识(10)----Join 时的三种算法简介
我们书写查询语句的时候,Join 参数之前可以是下面三个 { LOOP | MERGE | HASH } JOIN . 如果不使用,则系统自己分析那种方式快,使用那种方式. 这其实是SQL Serv ...
- c语言求最小公倍数和最大公约数三种算法
C语言求最小公倍数和最大公约数三种算法(经典) 求最小公倍数算法: 最小公倍数=两整数的乘积÷最大公约数 求最大公约数算法: (1)辗转相除法 有两整数a和b: ① a%b得余数c ② 若c=0,则b ...
最新文章
- SLAM之特征匹配(一)————RANSAC-------OpenCV中findFundamentalMat函数使用的模型
- JAVA编译异常处理:java.lang.OutOfMemoryError: PermGen space
- vue 计算属性和data_vue之watch和计算属性computed
- 先弄个XML解析器代码抄一抄 慢慢研究 O(∩_∩)O哈哈~
- es6方法过滤掉两个数组中对象id值相等的项
- 聊聊同步、异步、阻塞与非阻塞
- 程序员的数学 pdf_作为一个程序员,分享我日常学习方式,自学渠道和方式
- BugkuCTF-MISC题低位的色彩
- 容器编排技术 -- kubernetes 通过环境变量向容器暴露 Pod 信息
- MFC之CString与const char* string 转换
- 使用WindowsXP中的网桥功能
- 【Vue3.0】—V- model‘ directives require no argument.
- 如何给单词快速加双引号
- 将IE的默认搜索引擎换成Google
- Anaconda 安装python时出错:Collecting package metadata (current_repodata.json): failed
- 工作杂谈:由IT行业技术变革 谈当今技术趋势
- 书家必备——容易寫錯用錯的繁體字一百例
- Android通过MediaStore获取音乐文件信息的方法
- 【李佳辉_周报_2022.9.25】
- window.scrollTo滚动
热门文章
- 借花献佛!一文了解OOM及解决方案,终局之战
- 布隆过滤器(Bloom Filter)算法
- 最新真实软件测试面试题分享
- 【迷你兔教程】硬盘数据恢复方法详解
- 精简版 — Hive开发常用操作
- mysql数据库连接数
- 202003关于手机设备、系统、型号排名等信息
- 图卷积网络GCN(Graph Convolution Network)(一)研究背景和空域卷积
- 主板插槽上的内存条属于计算机存储系统中的,电脑插了两个8G的内存条,可是在属性里面查看是“16G(8G可用)”,这是怎么回事?...
- 张涵予韩国备受宠爱 《集结号》勇闯韩国票房