Follow me on GitHub

Java 四大引用类型

使用可达性分析算法判断对象是否存活时,涉及到“引用”的概念,实际上现代 Java 有 4 种引用类型,不同引用类型对垃圾回收的影响不同,有时即使存在到 GC root 的 引用链,但由于引用类型的原因,该对象也可能被垃圾回收。

Java 1.2 以后,共有 4 种引用类型,它们的引用强度依次降低:

  • 强引用(Strong Reference)
  • 软引用(Soft Reference)
  • 弱引用(Weak Reference)
  • 虚引用(Phantom Reference)

因此对象共有 5 种引用状态:

  1. 未引用
  2. 分别被强、软、弱、虚引用

原本对象只有被引用、未引用两种状态,扩充到 5 种状态是为了更细致地描述对象与 GC 的关系,从而实现更加智能的 GC 策略。

强引用

最普通、常见的引用:

1
Object x = new Object();

只要对象被强引用,GC 永远不会回收该对象。

软引用

1
SoftReference<Object> x = new SoftReference<>(new Object());

用于描述 有用但非必须 对象,若对象仅被软引用,则:

  1. JVM 即将抛出 OOM 异常之前,会 再次 回收这些对象;
  2. 第二次回收后,若还是内存不足,才真正抛出 OOM;

软引用是抛出 OOM 异常前的一次自我救赎,可在内存紧张场景下实现 高速缓存

弱引用

1
WeakReference<Object> x = new WeakReference<>(new Object());

仅被弱引用的对象,每次 GC 必然被回收,无论内存是否不足,其生命周期仅在两次 GC 之间。

弱引用同样可用于实现 缓存

虚引用

最弱的引用:

  • 虚引用对 GC 无任何影响,即仅被虚引用的对象为 不可达,可被回收;
  • 无法通过虚引用获取对象实例(已丧失作为引用的最后尊严);

虚引用的唯一用处是对象被 GC 时收到一个系统通知。