java lru 队列_Java LinkedHashMap 和 LRU算法

问题:使用Java完成一个简单的LRU算法

什么是LRU算法

LRU(Least Recently Used),也就是最近最少使用。一种有限的空间资源管理的解决方案,会在空间资源不足的情况下移除掉最近没被使用过的数据,以保证接下来需要的空间资源。

在现在通用的操作系统中为了解决内存不足这个问题,提出了虚拟内存这种解决方案,其实虚拟内存也就是将机器的内存分为多个页面(提个小问题,一个页面包含了多少kb的空间?),内存中只存放当前需要的页面信息,暂时不使用的内存数据就保存到磁盘中。这可以很好的解决内存不足的问题。当然了这就无故出现页面交换的情况,使得读取内存的速度降低(磁盘的读取速度远小于内存的读取速度),这种方案肯定有利有弊,只需要我们的服务能够接受这种情况,那就完全没有问题。

Redis做为一种内存数据库,内存大小对数据库的影响更重要,所以redis也需要及时的移除掉那些过期数据。在redis中有定时清楚、惰性删除、定期删除,但是其策略主要分为两种,基于访问时间和基于访问频率。基于访问时间就是LRU算法,看看LRU算法的图解过程,如下图。

e26a2301f97b

image.png

先定义好一个定长的队列

按照FIFO的流程,依次申请一段空间

直到队列被占满了,出现内存不足的情况,淘汰策略开始工作

会淘汰队列中最先进入的数据,最先进去的数据也就是最近最久未被使用的数据,然后把其移除出队列

LRU 算法小demo

整体的算法实现没有太多的难度,维护一个有限长度的队列的进出,需要移除或者插入数据。时间复杂度可能会是个问题。

队列如果是链表,则移除数据的时间复杂度是O(1),但是查找数据的时间复杂度是O(n)

队列如果是数组,则移除数据的时间复杂度是O(n),而且移除数据还伴随着数组的平行移动,查找数据也是O(n),除非另外再加一个Map存储其索引值会使得其查找的速度降低到O(1),但是却又提高了空间复杂度

接下来写个基于数组的LRU的简单代码

public class LruDemo {

private Object[] items;

private HashMap map;

private int size;

private int index;

public LruDemo() {

this(8);

}

public LruDemo(int size) {

this.size = size;

this.items = new Object[size];

this.map = new HashMap<>(16);

this.index = 0;

}

public void put(T t) {

Integer value = map.get(t);

if (value == null) {

if (index >= size) {

// 满了,需要移除第一个元素

for(int i=1; i

items[i-1] = items[i];

map.replace((T)items[i-1], i);

}

ind

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值