Skip to content

强引用、若引用、虚引用和幻象引用的区别

cxuan edited this page Jun 15, 2020 · 1 revision

我们说的不同的引用类型其实都是逻辑上的,而对于虚拟机来说,主要体现的是对象的不同的可达性(reachable) 状态和对垃圾收集(garbage collector)的影响。

可以通过下面的流程来对对象的生命周期做一个总结

对象被创建并初始化,对象在运行时被使用,然后离开对象的作用域,对象会变成不可达并会被垃圾收集器回收。图中用红色标明的区域表示对象处于强可达阶段。

JDK1.2 介绍了 java.lang.ref 包,对象的生命周期有四个阶段:􏲧强可达􏰛(Strongly Reachable􏰜)软可达(Soft Reachable􏰜)弱可达(Weak Reachable􏰜)幻象可达(Phantom Reachable􏰜)

如果只讨论符合垃圾回收条件的对象,那么只有三种:软可达、弱可达和幻象可达。

  • 软可达:软可达就是􏱬我们只能通过软引用􏳂才能访问的状态,软可达的对象是由 SoftReference 引用的对象,并且没有强引用的对象。软引用是用来描述一些还有用但是非必须的对象。垃圾收集器会尽可能长时间的保留软引用的对象,但是会在发生 OutOfMemoryError 之前,回收软引用的对象。如果回收完软引用的对象,内存还是不够分配的话,就会直接抛出 OutOfMemoryError。

  • 弱可达:弱可达的对象是 WeakReference 引用的对象。垃圾收集器可以随时收集弱引用的对象,不会尝试保留软引用的对象。

  • 幻象可达:幻象可达是由 PhantomReference 引用的对象,幻象可达就是没有强、软、弱引用进行关联,并且已经被 finalize 过了,只有幻象引用指向这个对象的时候。

除此之外,还有强可达和不可达的两种可达性判断条件

  • 强可达:就是一个对象刚被创建、初始化、使用中的对象都是处于强可达的状态
  • 不可达(unreachable):处于不可达的对象就意味着对象可以被清除了。

下面是一个不同可达性状态的转换图

判断可达性条件,也是 JVM 垃圾收集器决定如何处理对象的一部分考虑因素。

所有的对象可达性引用都是 java.lang.ref.Reference 的子类,它里面有一个get() 方法,返回引用对象。 如果已通过程序或垃圾收集器清除了此引用对象,则此方法返回 null 。也就是说,除了幻象引用外,软引用和弱引用都是可以得到对象的。而且这些对象可以人为拯救,变为强引用,例如把 this 关键字赋值给对象,只要重新和引用链上的任意一个对象建立关联即可。

Clone this wiki locally