缓存淘汰策略:
FIFO:先入先出策略
LFU:最少使用策略
LRU:最近最少使用策略
 
链表的数据结构:
可以看到,数组需要连续的内存空间,当内存空间充足但不连续时,也会申请失败触发GC,链表则可以是零散的。
常见的链表结构有:单链表,双向链表,循环链表等。
以单链表为例
每个节点除了存储数据以外,还要存储下一个节点地址,我们称之为后继指针。
头结点记录链表的基地址,尾节点的后继指针指向的是空地址null
循环链表:
双向链表:
双向循环链表:
 
双向链表插入,删除操作的时间复杂度是O(1)
单链表插入,删除操作的时间复杂度是O(n)
链表随机访问的时间复杂度是O(n)
 
注意:
单纯删除的时间复杂度是O(1),但往往删除前需要根据下标查找,时间复杂度为O(n)
针对删除操作与插入操作,由于单链表没有记录前驱节点位置,所以在删除与插入时,需要重新遍历链表,而双向链表则不需要。
java语言中,LinkedHashMap使用的就是双向链表。双向链表虽然比较耗费内存空间,但是性能更好,这是一种空间换时间的设计思想。
 
数组与链表各有利弊,数组对于缓存十分友好,且简单易用,缺点是数组是定长的,而容器如ArrayList,虽然支持动态扩容,但在扩容的时候需要重新分配空间且拷贝数据,十分损耗性能与内存。链表则会损耗更多的内存空间,并且会造成内存碎片,在java语言中,使用不当可能导致频繁的GC。
实际使用过程,应当根据场景选择使用数组还是链表。
 
使用链表实现LRU缓存淘汰算法:
使用单向链表存储缓存数据
缓存读取一个数据以后,遍历单向链表,有两种情况:
1.链表中已经存在,删除该数据,并且存储在链表头部
2.链表中不存在,又分为两种情况
    链表未满,直接插入到链表头部
    链表已满,删除尾部数据,将该数据存在链表头部
 
“数组简单易用,在实现上使用的是连续的内存空间,可以借助 CPU 的缓存机制,预读数组中的数据,所以访问效率更高。而链表在内存中并不是连续存储,所以对 CPU 缓存不友好,没办法有效预读。” 这里的CPU缓存机制指的是什么?为什么就数组更好了?
 
CPU在从内存读取数据的时候,会先把读取到的数据加载到CPU的缓存中。而CPU每次从内存读取数据并不是只读取那个特定要访问的地址,而是读取一个数据块(这个大小我不太确定)并保存到CPU缓存中,然后下次访问内存数据的时候就会先从CPU缓存开始查找,如果找到就不需要再从内存中取。这样就实现了比内存访问速度更快的机制,也就是CPU缓存存在的意义:为了弥补内存访问速度过慢与CPU执行速度快之间的差异而引入。
对于数组来说,存储空间是连续的,所以在加载某个下标的时候可以把以后的几个下标元素也加载到CPU缓存这样执行速度会快于存储空间不连续的链表存储。
Cache Line 是 Cache 与 DRAM 同步的最小单位. 典型的虚拟内存页面大小为 4KB,而典型的 Cache line 通常的大小为 32 或 64 字节
 
 

链表:如何实现LRU缓存淘汰算法?的更多相关文章

  1. 04 | 链表(上):如何实现LRU缓存淘汰算法?

    今天我们来聊聊“链表(Linked list)”这个数据结构.学习链表有什么用呢?为了回答这个问题,我们先来讨论一个经典的链表应用场景,那就是+LRU+缓存淘汰算法. 缓存是一种提高数据读取性能的技术 ...

  2. 数据结构与算法之美 06 | 链表(上)-如何实现LRU缓存淘汰算法

    常见的缓存淘汰策略: 先进先出 FIFO 最少使用LFU(Least Frequently Used) 最近最少使用 LRU(Least Recently Used) 链表定义: 链表也是线性表的一种 ...

  3. 《数据结构与算法之美》 <04>链表(上):如何实现LRU缓存淘汰算法?

    今天我们来聊聊“链表(Linked list)”这个数据结构.学习链表有什么用呢?为了回答这个问题,我们先来讨论一个经典的链表应用场景,那就是 LRU 缓存淘汰算法. 缓存是一种提高数据读取性能的技术 ...

  4. 链表(上):如何实现LRU缓存淘汰算法?

    一.什么是链表 和数组一样,链表也是一种线性表. 从内存结构来看,链表的内存结构是不连续的内存空间,是将一组零散的内存块串联起来,从而进行数据存储的数据结构. 链表中的每一个内存块被称为节点Node. ...

  5. Chapter 6 链表(上):如何实现LRU缓存淘汰算法?

    缓存淘汰策略: 一.什么是链表? 1.和数组一样,链表也是一种线性表. 2.从内存结构来看,链表的内存结构是不连续的内存空间,是将一组零散的内存块串联起来,从而进行数据存储的数据结构. 3.链表中的每 ...

  6. 详解工程师不可不会的LRU缓存淘汰算法

    大家好,欢迎大家来到算法数据结构专题,今天我们和大家聊一个非常常用的算法,叫做LRU. LRU的英文全称是Least Recently Used,也即最不经常使用.我们看着好像挺迷糊的,其实这个含义要 ...

  7. LRU缓存淘汰算法

    什么是LRU算法? LRU是Least Recently Used的缩写,即最近最少使用,在有限的内容块中存储最近使用次数最多的数据,当内容块已满时,把最少使用的数据删除以便存储新的内容.

  8. 昨天面试被问到的 缓存淘汰算法FIFO、LRU、LFU及Java实现

    缓存淘汰算法 在高并发.高性能的质量要求不断提高时,我们首先会想到的就是利用缓存予以应对. 第一次请求时把计算好的结果存放在缓存中,下次遇到同样的请求时,把之前保存在缓存中的数据直接拿来使用. 但是, ...

  9. 图解缓存淘汰算法二之LFU

    1.概念分析 LFU(Least Frequently Used)即最近最不常用.从名字上来分析,这是一个基于访问频率的算法.与LRU不同,LRU是基于时间的,会将时间上最不常访问的数据淘汰;LFU为 ...

随机推荐

  1. 小程序组件-swipe多页切换,并支持下拉刷新,上拉加载,menu动态联动切换

    前言 最近一个小程序项目中遇到一个需求,就是实现类似资讯类app的多页面切换的那种效果, 如下图: 最终效果: 1.功能分析 首先实现这个功能分为三步: 实现顶部menu菜单 实现多页面滑动切换 支持 ...

  2. 基于lua-nginx-module(openresty)的WEB应用防火墙

    独乐乐,不如众乐乐,分享给大家一篇WEB应用防火墙的文章,基于Lua+ Nginx实现.以下是ngx_lua_waf的作者全文输出. Github地址:https://github.com/loves ...

  3. RabbitMQ(一):RabbitMQ快速入门

    RabbitMQ是目前非常热门的一款消息中间件,不管是互联网大厂还是中小企业都在大量使用.作为一名合格的开发者,有必要对RabbitMQ有所了解,本文是RabbitMQ快速入门文章. RabbitMQ ...

  4. poi解析excel文件报错

    getFileMagic() only operates on streams which support mark(int) 使用 bis 解决 BufferedInputStream bis = ...

  5. 个人永久性免费-Excel催化剂功能第70波-工作薄外部链接维护管理

    Excel在数据领域万物互联的特性,其中一个使用场景是连接非本工作薄的外部性文件内容,如其他Excel工作薄文件里的内容或直接用OLE对象的方式嵌入一个文件链接,使其在不离开Excel环境,也可提供类 ...

  6. Jmeter(1):使用TCP取样器与socket接口进行简单通信

    一个小任务:服务器与客户端连接,每次发送50个随机生成的字符,两秒发送一次 失败过太多次,然后昨晚终于跑通了,心情激动,于是清均第一篇博客就诞生了. 之前不了解jmeter,想过单纯用java编写服务 ...

  7. vijos p1484 ISBN号码

    #include<iostream>#include<string>#include<cctype>using namespace std;int main() { ...

  8. Amdahl定律理解

    其中,a为并行计算部分所占比例,k为并行处理的个数. 当1-a=0时,(没有串行,只有并行)最大加速比s=n: 当a=0时,(只有串行,没有并行)最小加速比s=1: 当k→∞时,s → 1 /(1-a ...

  9. 机器学习-特征值,svd分解

    求矩阵的秩 设 ,已知r(A)=2,则参数x,y分别是 解:任意三阶子式=0,有二阶子式≠0,但是这些子式比较多,可以使用初等变换,因为初等变换不改变矩阵的秩,可以将矩阵通过初等行(列)变换,化为行阶 ...

  10. vue中el-upload上传多图片且携带参数,批量而不是一张一张的解决方案

    现在前端基本不是vue技术栈就是react技术栈. vue技术栈最常用的就是element-ui的ui框架了. 在项目中,我们经常会碰到这种需求:批量上传文件 element-ui 确实也为我们提供了 ...