jvm四种引用

Java中的引用一共有四种,它们分别是强引用、软引用、弱引用和虚引用,下面我们来分别介绍。

1 首先来说说强引用,强引用就是我们平常用的类似于“Object obj = new Object()”的引用,只要obj的生命周期没结束,或者没有显示地把obj指向为null,那么JVM永远不会回收这种对象

2 软引用相对强引用来说就要脆弱一点,JVM正常运行时,软引用和强引用没什么区别,但是当内存不够用时,濒临逸出的情况下,JVM的垃圾收集器就会把软引用的对象回收。在JDK中提供了SoftReference类来实现软引用,如下图的代码示例所示:

JVM如何判断一个Java对象是否可以回收

软引用代码示例

如上图代码,我们定义了SoftReferenceTest类,并重写了finalize方法,在main方法中我们往一个list里不断加值,使程序出现内存逸出的可能,只要我们将while循环中的阈值调大,就会输出finalize方法中的内容,调小就不会输出,下图便是调大时的输出。由于软引用自身的特点,所以比较适合作为应用的缓存。

JVM如何判断一个Java对象是否可以回收

3 弱引用比软引用更加脆弱,弱引用的对象将会在下一次的gc被回收,不管JVM内存被占用多还是少。在JDK中使用WeakReference来实现弱引用,代码示例如下图所示:

JVM如何判断一个Java对象是否可以回收

弱引用代码示例

上图代码中我们显示执行了一次gc,弱引用将会被回收,执行结果如下图:

JVM如何判断一个Java对象是否可以回收

4 虚引用是最脆弱的引用,随时都有可能被回收,我们没有办法通过一个虚引用来获得对象,即使在没有gc之前。虚引用需要和一个引用队列配合使用,在JDK中提供了PhantomReference来实现虚引用,代码示例如下图:

JVM如何判断一个Java对象是否可以回收

虚引用代码示例

由于虚引用没有办法访问对象实例,所以我们无法通过对象实例来判断是否被回收,但是我们传入引用队列,在对象被真正清除时,将会被加入到引用队列中,referenceQueue.remove(2000)将会阻塞2秒等待对象入队列,并移除打印。可以看下图输出,可以看出第一次gc虽然执行了finalize方法,但是对象并没有马上被清除,而是在第二次gc的时候才真正被清除。这是由于PhantomReference的处理过程和上面的引用不同,如果重写了finalize方法,那么必须保证finalize方法运行完之后才能加入引用队列,所以如果将代码中的finalize方法取掉,那么在第一次gc之后就可以加入到引用队列。

JVM如何判断一个Java对象是否可以回收

转自:https://blog.csdn.net/weixin_28760063/article/details/81271827

猜你喜欢

转载自blog.csdn.net/u010002184/article/details/89364793
今日推荐