Java 四种引用类型


四种引用类型

1. 强引用

强引用就是最普通的引用方式。

GC 时,只要堆中的对象实例存在强引用与之关联,则绝不会被垃圾回收。

Object o = new Object();

方法中的局部变量的强引用会在方法退出栈帧后自动销毁引用。

对于类的全局变量,消除强引用的方法是对强引用赋值为 null。这样可以帮助强引用全局变量的垃圾回收。

  • 全局变量:类变量 static, 类实例变量
o = null;

2. 软引用 SoftReference

软引用的对象会在内存不足时被 GC 回收。

  • 当没被回收时,软可达对象可以像强引用一样被程序正常访问和使用
  • SoftReference.get() 会返回对象实例的强引用
    • 但若对象实例被 GC 回收后,将返回 null

若对象实例与 GC Roots 之间不存在强引用,只存在软引用,则该对象状态为 软可达 状态。

String str = new String("abc");                                     // 强引用
SoftReference<String> softRef=new SoftReference<String>(str);       // 软引用

str = null;             // 消除强引用,该 String 实例变为软可达状态
str = softRef.get();    // 重新关联强引用

3. 弱引用 WeakReference

GC 进行垃圾回收时,无论堆内存是否充足,都会回收弱引用对象。

若对象实例与 GC Roots 之间只存在弱引用,则称为 弱可达 状态。

String str = new String("abc");    
WeakReference<String> abcWeakRef = new WeakReference<String>(str);
str = null;

软引用 与 弱引用

  • 如果缓存的对象较大,使用频率较高,使用软引用较好
  • 如果缓存的对象较小,视频频率较低,使用弱引用较好

4. 虚引用 PhantomReference

虚引用作用在于跟踪垃圾回收过程,在对象被收集器回收时收到一个系统通知。 当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在垃圾回收后,将这个虚引用加入引用队列,在其关联的虚引用出队前,不会彻底销毁该对象。

  • 可以通过检查引用队列中是否有相应的虚引用来得知对象被 GC 的时机,来进行销毁前的一些操作,比如说资源释放等。

如果一个对象没有强引用和软引用,对于垃圾回收器而言便是可以被清除的,在清除之前,会调用其 finalize() 方法,如果一个对象已经被调用过 finalize() 方法但是还没有被释放,它就变成了一个虚可达对象。

  • finalize() 方法是 Object 类的方法,现在已经不建议被使用。

事实上,虚引用有一个很重要的用途就是用来做堆外内存的释放,DirectByteBuffer 就是通过虚引用来实现堆外内存的释放的。


文章作者: Yu Yang
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Yu Yang !
  目录