LRU(1)

LRU是"Least Recently Used"(最近最少使用)的缩写,它是一种常用的页面置换算法和缓存淘汰策略。当计算机系统的内存或缓存资源有限时,LRU算法根据的历史访问记录来决定哪些数据应该被保留在内存或缓存中,哪些被淘汰。其核心思想是“如果一个数据项在最近一段时间内没有被访问过,那再未来的一段时间内它被访问的可能型也比较小”。因此,当需要腾出空间给新的数据项时,LRU会选择哪些最长时间未被使用的数据项目进行淘汰。

页面访问序列232152453
第1块2/12/12/22/22/02/22/02/03/1
第2块3/13/13/15/15/15/05/15/0
第3块1/11/01/04/14/14/0
缺页否(*)******
换出页面3,112
随机
换进页面231543

 

LRU工作原理

LRU可以通过多种方式来跟踪数据项的使用情况:

  • 基于栈的方式:可以利用一个特殊的栈来保存当前正在使用的各个页面的页面号。每当进程访问某页面时,便将该页面号压入栈顶,其他的页面号往栈底移。这样,栈顶始终时最新被访问的页面编号,而栈底则时最近最久未访问的页面编号。

  • 双向链表与哈希表结合:为了确保getput方法的时间复杂度为O(1),通常采用双向链表加哈希表的数据结构。哈希表用于快速查找是否再缓存中,而双向链表则用来维护元素的顺序,保证新插入或最近访问过的袁术位于链表头部,而最久未使用的袁术位于链表尾部。

  • 数据访问记录:LRU 算法会为每个缓存的数据块维护一个访问时间戳或者访问顺序记录。每当一个数据块被访问(读或写操作)时,它的时间戳就会更新,或者它在访问顺序记录中的位置就会调整到最新(例如,移到队列的头部)。

  • 缓存空间已满时的处理

    1. 当缓存空间已满,需要放入新的数据块时,LRU 算法会查找访问时间最早或者最久未被访问的数据块。

    2. 例如,假设有一个缓存大小为 3 的数据缓存,里面已经存放了数据块 A、B、C。此时,如果要访问数据块 D,由于缓存已满,LRU 算法会检查 A、B、C 这三个数据块的访问顺序。假设 A 是最早被访问的(也就是最近最少使用的),那么 A 就会被从缓存中移除,D 则会被放入缓存,并且 D 会被标记为最新访问的数据块。

  • 使用数据结构实现

    1. 一种常见的实现方式是使用链表和哈希表结合。链表用于维护数据块的访问顺序,新访问的数据块会被移到链表头部。哈希表用于快速查找数据块在链表中的位置,这样可以在 O (1) 时间复杂度内完成数据的访问和更新操作。

    2. 比如,在一个简单的 LRU 缓存实现中,每次访问一个数据块,通过哈希表可以快速定位到链表中的节点,然后将该节点从原来的位置移除并插入到链表头部,以此来更新访问顺序。如果缓存已满,需要淘汰数据块时,直接删除链表尾部的数据块即可,因为链表尾部的数据块就是最近最少使用的数据块。

LRU 的应用场景

LRU 在计算机系统的缓存管理中应用广泛,如 CPU 缓存、数据库缓存等。在 Web 服务器的内容缓存中也经常使用,它可以帮助服务器快速响应客户端的请求。例如,当用户频繁访问某些网页时,这些网页的数据就会被保留在缓存中,而那些长时间无人访问的网页数据可能会被淘汰,从而提高缓存的命中率和系统的整体性能。

LRU优势

LRU 算法能够很好地适应访问模式的变化。如果数据的访问频率发生改变,它会自动调整缓存中的数据,使得经常被访问的数据能够留在缓存中。并且它的实现相对简单,与其他一些复杂的缓存淘汰策略相比,它的时间复杂度和空间复杂度在很多情况下都比较容易控制,能够在性能和资源利用之间取得较好的平衡。

缓存系统

数据库查询缓存

  • 在企业级应用中,数据库查询操作通常是比较耗时的。例如,在一个电商系统中,商品信息的查询很频繁。通过使用 LRU 缓存,可以将最近查询的商品信息存储在内存中。当有新的查询请求时,首先在缓存中查找。如果缓存命中,就直接返回结果,避免了重复的数据库查询。

  • 假设缓存大小为 100 条商品信息记录。当查询商品 A 时,LRU 算法会将商品 A 的信息缓存起来。如果缓存已满,并且又要缓存新的商品信息,它会根据 LRU 策略,淘汰最久未被查询的商品信息。这样可以大大提高系统的响应速度,减少数据库的负载。

Web 服务器内容缓存

  • 在 Web 服务器中,对于经常访问的网页内容,如 HTML 文件、图片、脚本等可以进行缓存。以一个新闻网站为例,热门新闻页面会被大量用户访问。服务器可以使用 LRU 缓存来存储这些热门页面的内容。

  • 比如,一个 Web 服务器的缓存可以存储 1000 个网页内容。当用户请求一个网页时,服务器先检查 LRU 缓存。如果页面在缓存中,就直接返回缓存中的内容,提高了网页的加载速度。当缓存满了,LRU 算法会淘汰那些访问次数最少的网页内容,保证缓存中总是存储最有可能被访问的内容。

内存管理

Java 虚拟机(JVM)中的对象缓存

  • 在 JVM 内部,对于一些频繁创建和销毁的对象,可以使用 LRU 缓存来管理。例如,在一个图形处理应用中,会频繁创建和使用一些图形对象,像形状、颜色等对象。

  • 假设 JVM 中有一个小型的对象缓存,大小为 50 个对象。这些图形对象可以被缓存起来。当需要再次使用某个图形对象时,首先在缓存中查找。如果缓存中有,就直接使用,避免了重新创建对象的开销。LRU 算法会确保缓存中的对象是最近最有可能被使用的,当缓存满时,会淘汰最久未被使用的对象。

分布式系统中的缓存

分布式缓存集群(如 Redis)

  • 在分布式系统中,多个节点可能会共享一个缓存集群。LRU 策略可以用于管理这些缓存节点中的数据。例如,在一个电商系统的分布式缓存中,不同的服务器节点可能会访问和缓存用户的购物车信息。

  • 假设分布式缓存集群中有 10 个节点,每个节点都有自己的 LRU 缓存。当某个节点需要存储新的购物车信息,但缓存已满时,LRU 算法会在该节点的缓存中淘汰最久未被访问的购物车信息,从而保证缓存的高效利用,提高整个分布式系统的性能。这种应用场景可以有效避免缓存数据的不一致性和过期问题,使得分布式缓存能够更好地服务于多个节点的应用需求。

LRU局限性

Java中使用链表实现的LRU(Least Recently Used)缓存虽然在很多情况下能够有效地提高系统性能,但也存在一些局限性。这些局限性主要体现在内存占用、并发处理能力以及面对特定访问模式时的表现上。

内存占用

首先,基于链表和哈希表的数据结构实现LRU缓存需要额外的空间来存储指针信息。对于每个缓存项而言,不仅需要保存实际的数据内容,还需要维护前驱和后继节点的引用。当缓存容量较大时,这种额外的开销可能会变得显著,导致整体内存消耗增加。此外,频繁地进行插入和删除操作会导致内存分配和释放活动增多,进而可能引起内存碎片化问题。

并发性能

其次,在高并发场景下,链表操作可能会成为性能瓶颈。由于双向链表不是线程安全的,默认情况下多个线程同时访问或修改同一个LRU缓存实例时,必须采取适当的同步措施以确保数据一致性。然而,全局加锁的方式虽然简单直接,但在多线程环境下容易造成争用热点,影响吞吐量。因此,如果应用对并发度要求较高,则需要考虑更复杂的同步策略或者采用其他更适合并发环境的数据结构。

对特定访问模式的支持

最后,传统的LRU算法仅考虑了最近最少使用的特性,而忽略了某些数据可能被频繁访问的事实。这意味着一旦出现周期性的批量读取请求或者其他非典型的访问模式,LRU缓存有可能会因为“缓存污染”而导致命中率下降。例如,当发生偶发性的大量历史数据查询时,原本应该保留下来的热门数据可能会被新进来的冷门数据所替代,从而降低了缓存的有效性。

为了解决上述问题,业界提出了多种改进方案:

  • LRU-K:通过记录每个缓存项最近K次访问的时间戳,选择淘汰第K次访问时间最久远的那个元素。这种方法可以在一定程度上缓解短期突发流量对缓存的影响。

  • 2Q (Two Queues):该算法将缓存分为两个队列,分别存放短期访问频率较低与长期访问频率较高的项目。当某个项目从一个队列迁移到另一个队列时,表明它可能是经常使用的对象,有助于提升缓存命中率。

  • ARC (Adaptive Replacement Cache):这是一种自适应替换策略,通过动态调整两个LRU列表(T1 和 T2)及相应的历史列表(B1 和 B2),使得算法能够在不同类型的访问模式下都表现出色。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/503513.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Centos 下安装 GitLab16.2.1

参考 https://blog.csdn.net/weixin_46059351/article/details/140649426 https://blog.csdn.net/qq_46028493/article/details/144993598 Centos 安装 GitLab 修改 yum 的配置 首先查看目前配置的 yum: cat /etc/yum.repos.d/CentOS-Base.repo应该是这个样子…

uniapp 微信小程序 自定义日历组件

效果图 功能&#xff1a;可以记录当天是否有某些任务或者某些记录 具体使用&#xff1a; 子组件代码 <template><view class"Accumulate"><view class"bx"><view class"bxx"><view class"plank"><…

刚体变换矩阵的逆

刚体运动中的变换矩阵为&#xff1a; 求得变换矩阵的逆矩阵为&#xff1a; opencv应用 cv::Mat R; cv::Mat t;R.t(), -R.t()*t

php反序列化 ctf例题演示 框架安全(TP,Yii,Laravel) phpggc生成框架利用pop

前言 php反序列化的框架的利用的pop是非常难写的 并且 我们不知道他的利用方法 所以PHPGGC是一个包含unserialize()有效载荷的库以及一个从命令行或以编程方式生成它们的工具。当在您没有代码的网站上遇到反序列化时&#xff0c;或者只是在尝试构建漏洞时&#xff0c;此工具…

【游戏设计原理】53 - 解决问题的障碍

1. 分析并总结原理 核心观点 游戏本质是一系列问题解决的过程&#xff0c;通过设计巧妙的问题和决策场景&#xff0c;游戏能激发玩家的兴趣和投入感。然而&#xff0c;当问题解决的过程被阻碍时&#xff0c;会降低玩家的体验甚至让他们放弃游戏。文中提到的四种障碍反映了玩家…

线性代数考研笔记

行列式 背景 分子行列式&#xff1a;求哪个未知数&#xff0c;就把b1&#xff0c;b2放在对应的位置 分母行列式&#xff1a;系数对应写即可 全排列与逆序数 1 3 2&#xff1a;逆序数为1 奇排列 1 2 3&#xff1a;逆序数为0 偶排列 将 1 3 2 只需将3 2交换1次就可以还原原…

LabVIEW四旋翼飞行器姿态监测系统

四旋翼飞行器姿态监测系统是一个集成了高度、速度、俯仰角与滚转角数据采集与分析的系统&#xff0c;提高飞行器在复杂环境中的操作精确度与安全性。系统利用LabVIEW平台与硬件传感器相结合&#xff0c;实现实时数据处理与显示&#xff0c;有效地提升了四旋翼飞行器的监测与控制…

STM32之CAN通讯(十一)

STM32F407 系列文章 - CAN通讯&#xff08;十一&#xff09; 目录 前言 一、CAN 二、CAN驱动电路 三、CAN软件设计 1.CAN状态初始化 2.头文件相关定义 3.接收中断服务函数 4.用户层使用 1.用户层相关定义 2.发送数据 3.接收数据 1.查询方式处理 2.中断方式处理 3…

添加系统级res资源包

//刚做完自定义res资源包的配置&#xff0c;这里做一下关于在配置过程中出现的问题和解决方法作一下记录。 资源的引用格式为&#xff1a; 包名&#xff1a;资源类型/资源名以framework资源为例&#xff1a; android:style/Theme.Holo.Light这次需要配置与framework同级的资…

LabVIEW计算机软件著作权

计算机软件著作权是指软件开发者对其创作的软件作品享有的法律保护权利&#xff0c;目的是防止他人未经授权复制、修改或传播该软件。软件著作权不仅包括软件的源代码&#xff0c;还包括文档、界面设计、功能模块、程序逻辑等内容。通过登记软件著作权&#xff0c;开发者可以获…

unity学习13:gameobject的组件component以及tag, layer 归类

目录 1 gameobject component 是unity的基础 1.1 类比 1.2 为什么要这么设计&#xff1f; 2 从空物体开始 2.1 创建2个物体 2.2 给 empty gameobject添加组件 3 各种组件和新建组件 3.1 点击 add component可以添加各种组件 3.2 新建组件 3.3 组件的操作 3.4 特别的…

Vue项目中的问题汇总(持续更新中)

1.vue 循环 span 标签产生了间隙 代码如下&#xff1a; <template><div class"box"><span v-for"(item,index) in items" ::key"index">{{ item }}</span><span>修改</span><span>删除</span>…

ffmpeg7.0 合并2个 aac 文件

ffmpeg7.0 将2个aac文件合并。 #include <stdio.h>// 之所以增加__cplusplus的宏定义&#xff0c;是为了同时兼容gcc编译器和g编译器 #ifdef __cplusplus extern "C" { #endif #include <libavformat/avformat.h> #include <libavcodec/avcodec.h>…

Midjourney 应用:框架总结

Midjourney 应用&#xff1a;框架总结 官方的模板很简单&#xff0c;分成四个部分&#xff1a; 主体细节 & 背景风格、媒介、艺术家参数 我的总结 其实按照官方模板写&#xff0c;你已经能超过 90% 的初学者&#xff0c;但根据我的实验&#xff0c;我细化了他们的模板的…

JVM实战—OOM的定位和解决

1.如何对系统的OOM异常进行监控和报警 (1)最佳的解决方案 最佳的OOM监控方案就是&#xff1a;建立一套监控平台&#xff0c;比如搭建Zabbix、Open-Falcon之类的监控平台。如果有监控平台&#xff0c;就可以接入系统异常的监控和报警&#xff0c;可以设置当系统出现OOM异常&…

JVM实战—13.OOM的生产案例

大纲 1.每秒仅上百请求的系统为何会OOM(RPC超时时间设置过长导致QPS翻几倍) 2.Jetty服务器的NIO机制如何导致堆外内存溢出(S区太小 禁NIO的显式GC) 3.一次微服务架构下的RPC调用引发的OOM故障排查实践(MAT案例) 4.一次没有WHERE条件的SQL语句引发的OOM问题排查实践(使用MA…

【银河麒麟高级服务器操作系统实例】tcp半链接数溢出分析及处理全过程

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://document.kylinos.cn 服务器环境以及配置 系统环境 物理机/虚拟机/云…

visual studio 自动调整代码格式的问题:

1.取消自动调整格式 2.如果是想让代码显得更紧凑&#xff0c;上面的不动&#xff0c;按这个来&#xff1a;

javaEE-网络原理-1初识

目录 一.网络发展史 1.独立模式 2.网络互联 二.局域网LAN 1.基于网线直连&#xff1a; 2.基于集线器组件&#xff1a; 3.基于交换机组件&#xff1a; 4.基于交换机和路由器组件 ​编辑 三、广域网WAN 四、网络通信基础 1.ip地址 2.端口号&#xff1a; 3.协议 4.五…

三维卷积( 3D CNN)

三维卷积&#xff08; 3D CNN&#xff09; 1.什么是三维卷积 1.1 三维卷积简介 二维卷积是在单通道的一帧图像上进行滑窗操作&#xff0c;输入是高度H宽度W的二维矩阵。 三维卷积输入多了深度C这个维度&#xff0c;输入是高度H宽度W深度C的三维矩阵。在卷积神经网络中&…