虚引用详解与示例详细剖析

虚引用再论:

在上一次https://www.cnblogs.com/webor2006/protected/p/12660674.html学习了虚引用,其中还抛出了2个问题,回忆一下:

而先来看一下PhatomReference的方法定义:

其实对于上面的这两个问题可以从它的官方说明中找到答案,对于PhantomReference类在之前https://www.cnblogs.com/webor2006/p/12110089.html已经解读过了,回忆一下:

其中第一个问题“为啥PhatomReference的get()方法直接返回null?”,它的答案在这句话上:

如何理解?这里其实可以用一个假设法,假如我们可以通过它的get()方法获取它里面的referent对象的话,那么是不是我们可以用一个引用指向这个referent对象呢?那这种引用就有可能是强、软、弱三种情况出现,而如果是被强引用的话肯定该referent对象是不可能被回收的,那很明显就不满足虚引用的规则了,同样的如果被软、弱引用也会干扰到referent对象的回收的,所以这也是为啥get()方法永远返回null的原因,这里看一下get()方法的说明:

好,接下来再来解释一下第二个问题“为啥PhatomReference的构造方法只有接收两个参数(referent与queue)的这一种形式,而没有只接收referent这唯一参数的构造方法呢?像其它两个引用都有两个构造存在...”,先来看一下构造的说明:

而要想解释为啥只提供一个带队列的构造的原因,这里就得从虚引用的使用场景来解释了,如下:

当我们将一个对象封装到PhatomReference中时,这就意味着我们将永远也无法再访问到这个对象了,因为PhatomReference的get方法永远都会返回null;PhatomReference的主要作用并不在于可以让我们获取到其中封装的referent,而是在于当垃圾收集器回收其referent时,这个PhatomReference会被放置到与其关联的队列中,并且得到相应的通知,这就是PhatomReference存在的唯一目的

其中加粗的说明文字就能很好的解释了为啥只提供了一个带队列的构造函数了。

弱引用再论:

在上一次中,对于虚引用的示例中其实做了一个伏笔,回忆一下:

而根据弱引用的特点:

很明显咱们已经调了system.gc()了,当然我们也知道调这个不一定能让垃圾收集器进行真正的gc,但是为啥我们睡眠了5秒之久,一次也没看到弱引用对象被回收的结果呢?其实是可以达到我们想要的回收效果的,这里先分析一下为啥目前的代码看不到弱引用被回收的效果呢?

很明显弱引用引用了堆中的Date对象了,而造成看不到gc效果的原因在于这句话:

这个引用属于“”引用!!!!!哦,强引用对象的特点就能知道为啥看不到弱引用对象得不到回收的原因了,知道了原因之后,下面增加一句代码则就可以看到被回收的效果了,如下:

好,最后咱们再来对比一下软引用手动gc的情况:

这是因为:

而它的回收时机是在内存比较紧张的时候才会,并非垃圾回收器一扫描到就立马被回收,回忆一下这块的说明:

通过这样来回的探究,对于四大引用应该是非常之清楚了,还是相当有价值的。

posted on 2020-04-27 16:41  cexo  阅读(1368)  评论(1编辑  收藏  举报

导航