在创建具有非平凡finalize()
方法的对象时,JVM将创建以该对象为对象的Finalizer
(FinalReference
)。如果该对象也被“软/弱”或“幻影引用”包装,将会发生什么? GC是否会首先尝试使Finalizer
(调用finalize方法)入队,然后使另一个Reference或相反的对象入队?
答案 0 :(得分:2)
我认为,您的问题实际上与排队时间无关。
的通知部分在垃圾回收器确定引用对象的可到达性已更改为与引用类型相对应的值之后的一段时间,它将引用添加到关联的队列中。
(请注意“之后的某个时间”)
同样,所有引用类型都具有以下形式的语句:
假设垃圾收集器在某个时间点确定对象是弱可到达的。到那时,它将自动清除对该对象的所有弱引用,以及对所有其他弱可达对象的弱引用,这些对象都可以通过一系列强引用和软引用从该对象到达。同时,它将声明所有以前难以到达的对象都是可终结的。同时或在以后的某个时间,它将把那些新近清除的弱引用加入队列,该弱引用已在引用队列中注册。
(摘自WeakReference
;请注意“同时或以后”)
在实践中,垃圾收集器将发现的引用移交给另一个线程进行异步排队。由于未指定的延迟使应用程序从队列中检索引用的顺序不确定,因此在这里询问顺序毫无意义。
但是,我想您实际上对另一个“ 特定时间点”感兴趣,当“ 垃圾收集器确定引用对象的可到达性已更改为值对应于引用的类型”,并将决定自动清除引用并使其符合入队条件。
当混合使用多个不同类型的引用对象(包括Finalizer
引用但没有强引用)时,存在两种可能的情况:
请注意,一旦完成最终确定,就不再存在Finalizer
引用,但是在最终确定期间,可能会创建新的软或弱引用。因此,所产生的场景与具有简单finalize()
方法的对象的优化处理相同。没有Finalizer
引用,可以混合使用软引用,弱引用和幻像引用。当没有足够的参考依据时,我们又有两种可能的情况:
A 幻像引用在Java 9或更高版本中已清除。在以前的版本中,它们仅在未清除的情况下入队。