Java 中除了普通的强引用,基于 Reference 抽象类还有弱引用、软引用和幻引用。
在 Reference 类装载时,会通过 cinit
启动 Reference Handler 线程,辅助 GC。
private T referent;
volatile ReferenceQueue<? super T> queue;
volatile Reference next;
private transient Reference<T> discovered;
public void run() {
while (true) {
processPendingReferences();
}
}
弱引用在GC的过程中,会被特殊处理。在GC的过程中,以copy gc为例,所有存活的强引用都会被拷到新的survivor区域中,但是弱引用
不会被拷贝。
同时会把 WeakReference
都使用它的discovered
域串起来,在串的同时,把它的referent设置为 nul,如下图所示。(应该是 GC 使用上帝视角处理)
https://zhuanlan.zhihu.com/p/29415902
进行GC扫描时,遇到一个存活的WeakRef,发现它所引用的对象没有被forward,这就说明了,这个被引用的对象可能没有强引用在引用它了。我们就先把它放到链表里。
在GC以后对链表再做一次遍历,把还有强引用的情况删掉,并且把它的forward更新到弱引用的位置去。
扫描完成后,JVM会负责把WeakReference对象的引用置为NULL,然后,由ReferenceHandler线程再去处理这个链表。
SoftReference会至少经历1次gc而不被回收。