缓存淘汰策略:
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. 谷歌浏览器 Google Chrome 70.0.3538.102 便携版

    oogle Chrome 是由Google开发的一款设计简单.运行高效.支持扩展的浏览器,它基于高速WebKit/Blink内核和高性能JavaScript V8引擎,在支持多标签浏览的基础上,提供顺 ...

  2. mybatis基础配置

    我这个写的比较简略,是自己短时间记录的可能只适合自己看,新手或者不懂的建议看看下面大神这篇: https://www.cnblogs.com/homejim/p/9613205.html 1.MyBa ...

  3. [译]Vulkan教程(33)多重采样

    [译]Vulkan教程(33)多重采样 Multisampling 多重采样 Introduction 入门 Our program can now load multiple levels of d ...

  4. [记录]python的简单协程框架(回调+时间循环+select)

    # -*- coding: utf-8 -*- # @Time : 2018/12/15 18:55 # @File : coroutine.py #一个简单的 Coroutine 框架 import ...

  5. TreeMap原理实现及常用方法

    目录 一. TreeMap概述 二. 红黑树回顾 三. TreeMap构造 四. put方法 五. get 方法 六. remove方法 七. 遍历 八. 总结 前面我们分别讲了Map接口的两个实现类 ...

  6. 第一届合天杯河北科技大学网络安全技术大赛 web6 writeup

  7. 【原】docker部署单节点consul

    docker下部署单节点的consul,最重要的是在run consul时,配置-bootstrap-expect=1 docker run --name consul1 -d -p : -p : - ...

  8. 小记---idea springboot 报错没有get或者set方法

    给idea 安装一个插件即可

  9. SQL SERVER Suspect(质疑/挂起) 状态恢复

    数据库服务器,在断电时,偶尔会出现Suspect状态,导致数据库无法使用. 解决办法如下: 数据库名带‘[]’可以避免库名中带‘.’等特殊符号的情况. USE [master]GOALTER DATA ...

  10. tomcat用做图片服务器

    最近做了个小网站,就是用tinyce富文本编辑器,https://www.511easy.com/ 保持字体排版和图片 发现博客园的图片,一天之后就无法显示 就想着自己做一个图片服务器,上传图片到指定 ...