为什么幻像引用在排队时未清除它们?

2022-09-03 07:32:40

我们可以看到,“幻像可访问”与“不可访问”一样不可访问:§

如果一个对象既不是强、柔和的,也不是弱的可访问的,它已被最终确定,并且一些幻像引用引用它,则该对象是可幻像可访问的。

最后,当无法通过上述任何方式访问对象时,该对象是无法访问的,因此符合回收条件。

现在,从: http://download.oracle.com/javase/6/docs/api/java/lang/ref/PhantomReference.html

与软引用和弱引用不同,幻像引用在排队时不会由垃圾回收器自动清除。可通过幻像引用访问的对象将保持原样,直到清除所有此类引用或它们本身变得不可访问。

基本原理是什么?甚至有一个吗?

这是Java API怪癖的另一个典型案例吗?


答案 1

软引用在排队时被清除,因为软引用的主要用途是允许缓存大型对象,而清除软引用允许对大型缓存对象进行垃圾回收。

弱引用在排队时会被清除,因为弱引用的主要用途是允许引用对象而不阻止它被垃圾回收,因此在对象排队后立即清除引用可以对对象进行垃圾回收。

幻像引用在排队时不会被清除,因为幻像引用的一个用例是允许在对对象进行垃圾回收之前执行清理。如果不清除引用,该对象将保持幻像可访问(并且不符合垃圾回收的条件),直到用户清除对该对象的 PhantomReference 引用,或者 PhantomReference 本身被垃圾回收。

这里对此进行了解释,

如果一个对象既不是强的、柔和的,也不是弱的可访问的,它已被最终确定,并且一些幻像引用引用它,则该对象是可幻像可访问的。

最后,当无法通过上述任何方式访问对象时,该对象是无法访问的,因此符合回收条件。


答案 2

这在 JDK 9 中已更改。现在,幻像引用被清除,就像软引用和弱引用一样。相应的段落从Javadoc中删除。

与软引用和弱引用不同,幻像引用在排队时不会由垃圾回收器自动清除。可通过幻像引用访问的对象将保持原样,直到清除所有此类引用或它们本身变得不可访问。