博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
guava 缓存过期策略
阅读量:6242 次
发布时间:2019-06-22

本文共 2354 字,大约阅读时间需要 7 分钟。

hot3.png

google的guava可谓鼎鼎有名,最近在研究缓存,也就看看它是怎么处理缓存过期问题的;首先它并没有通过在后台起一个线程,不停去轮询。不这么做主要是为了效率吧,也就是所谓的惰性移除,在get时判断是否过期。那如果一直不访问,可能存在内存泄漏问题。

示例代码:

Cache
cache = CacheBuilder.newBuilder().expireAfterAccess(2,TimeUnit.SECONDS).build(); cache.put("a",1); System.out.println(cache.getIfPresent("a")); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(cache.getIfPresent("a"));

1,CacheBuilder默认的缓存实现为LocalCache,所以这里我们主要去研究LocalCache的getIfPresent 即可

2,通过观察,我们可以猜出LocalCache 是用类似于ConcurrentHashMap 的数据结构来保存数据的

3,这里我们主要看其Segment 的get 方法,然后进入getLiveEntry 方法,看名字感觉跟存活有关,点进去

ReferenceEntry
getLiveEntry(Object key, int hash, long now) {//获取值 ReferenceEntry
e = getEntry(key, hash); if (e == null) {//如果为空,返回空 return null; } else if (map.isExpired(e, now)) {//判断是否过期 tryExpireEntries(now); return null; } return e; }boolean isExpired(ReferenceEntry
entry, long now) { checkNotNull(entry); if (expiresAfterAccess() && (now - entry.getAccessTime() >= expireAfterAccessNanos)) { return true; } if (expiresAfterWrite() && (now - entry.getWriteTime() >= expireAfterWriteNanos)) { return true; } return false; }

maximumSize作用原理,猜想:应该是在put缓存时,检查是否达到了最大值,如果达到则用LRU算法移除一个cache

1,观察LocalCache#put

V put(K key, int hash, V value, boolean onlyIfAbsent) {      lock();      try {       ...        evictEntries(newEntry);//这行代码,看名字感觉就是它,点进去看        return null;      } finally {        unlock();        postWriteCleanup();      }    }void evictEntries(ReferenceEntry
newest) { .... while (totalWeight > maxSegmentWeight) { ReferenceEntry
e = getNextEvictable(); if (!removeEntry(e, e.getHash(), RemovalCause.SIZE)) { throw new AssertionError(); } } }

这里我们不妨看看它的LRU算法是如何实现的

ReferenceEntry
getNextEvictable() { for (ReferenceEntry
e : accessQueue) { int weight = e.getValueReference().getWeight(); if (weight > 0) { return e; } } throw new AssertionError(); }

发现它是用队列实现的,也就是在插入新缓存是有排序。

总结:

我们时常会有本地缓存的需求,这时不妨看看google是怎么做的,可以给我们一个参考

转载于:https://my.oschina.net/u/3574106/blog/3016413

你可能感兴趣的文章
MYSQL EXPLAIN 中的KEY_LEN的说明
查看>>
Linux笔记(VIM)
查看>>
pyrhon脚本小练习(9*9乘法表)
查看>>
Python按行读取文件
查看>>
Linux Shell从一个文件去掉包含在另一个文件的内容
查看>>
Linux CentOS6.5下编译安装MySQL 5.6.16
查看>>
CentOS 7 上systemctl 的用法
查看>>
极验验证的滑动验证码破解
查看>>
【深入Linux块设备驱动层次之一】整体层次
查看>>
Linux登录安全及用户操作审计 ,linux下清理日志脚本
查看>>
一个JS文件中引入另一个JS文件
查看>>
Laravel中pluck的使用——返回指定的字段值信息列表
查看>>
TCP Segment Offload(TSO)的实现原理浅析
查看>>
Android官方开发文档Training系列课程中文版:多样屏幕之支持不同的屏幕尺寸
查看>>
Redmine部署
查看>>
五种开源协议比较:BSD,Apache,GPL,LGPL,MIT
查看>>
Linux上编译hadoop-2.7.1的libhdfs.so和libhdfs.a
查看>>
mysql中函数greatest 与MAX区别
查看>>
ORA-01843: 无效的月份
查看>>
Centos网络管理(三)-网络配置相关
查看>>