Guava Cache实现原理——引用类型回收

系列文章:

Guava Cache实现原理——开篇&基本实现

Guava Cache实现原理——LRU回收实现

Guava Cache实现原理——引用类型回收

Guava Cache实现原理——高效回收技巧

 

目录

一、前言

二、实现

1、引用类型的基本使用

​2、引用类型的实现

3、引用类型的回收

4、总结

三、惯例


一、前言

上一篇文章我们已经介绍了Guava Cache的LRU算法的实现,本篇文章我们继续分析Guava Cache是如何对引用类型进行回收的。

 

二、实现

1、引用类型的基本使用

我们首先回顾下在Guava Cache中如何使用引用类型。在初始化Guava Cache的时候,我们通过weakkeys、weakValues或者softValues来设置对应的Key和Value为软引用或者弱引用。这样GC回收或者内存吃紧的时候就能够利用GC对相应的key或者value进行回收(前提是没有其他强引用)。

 

思考:为什么没有softKeys()

​2、引用类型的实现

熟悉Java引用类型使用的同学应该都能够想到如何实现了。就是根据具体的引用类型将value或者key封装成对应的Reference类。在Guava Cache中提供了如下三个类来实现对应的强引用、软引用和弱引用对象。

以下是弱引用的实现类。具体实现很简单就是继承实现Java的SoftReference类即可,其他类型类同,这里不再做具体介绍,具体请自行查看源码。

使用过引用类型的同学都知道,在构建引用类型的时候需要传递一个Queue队列,当引用类型被回收后就会被JVM放到这个Queue中。在Guava Cache中,在构建每个Segment的时候就会构建出对应的Queue(如下图)。后面在当前Segment中创建引用类型的时候就使用这个对应的Queue。

如下是软引用类型构建的时候的实现,即使用Segment的Queue直接构建出软引用对象,其他类同这里不再做详细介绍,自行查看源码。

3、引用类型的回收

上一节已经介绍过了,当引用类型(非强引用)被回收后,其对应的引用类型对象会被放到其初始化的队列中。于是我们只要通过不断从Queue中读取数据就知道哪些key或者value被回收了。

在Guava Cache中,引用类型的回收和之前的LRU回收一样,有两个地方会触发,其分别是:

  1. 在get的时候,如果tryLock获取到锁了,则进行回收。

  2. 在modify的时候(put|add|delete),此时肯定获取到了锁,直接进行回收。

具体回收都是调用drainReferenceQueues方法,如下:

如下则是对value的引用对象的时候过程,和普通的引用对象的处理类似。首先从Queue中获取到哪些引用类型的对象被回收了,然后在从map中将对应的引用类型进行移除操作。

如下是key的引用对象的回收过程代码:

4、总结

  1. 其实引用类型的回收很简单,就是利用了Reference的特性。

    当其引用的对象被回收后,就会将引用对象放到对应的Queue中。

    我们只需不断从Queue中获取出引用对象,然后将其从map中移除即可。

  2. 和LRU回收一样,在get的时候,如果获取到锁才执行回收。

    在modify操作中则直接回收。

三、惯例

如果你对本文有任何疑问或者高见,欢迎添加公众号共同交流探讨(添加公众号可以获得”Java高级架构“上10G的视频和图文资料哦)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

跳小闹成长记-跳爸

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值