如果一个终结器使一个对象变得可达,会发生什么?

7

在Java中,当对象即将被垃圾回收并且不可访问时(前提是该对象覆盖了finalize方法),会调用finalize方法。但是如果finalizer使得对象再次可访问,那么会发生什么呢?

5个回答

10

那么该对象就不会被垃圾回收,这就是所谓的对象复活。搜索一下这个术语,你应该可以找到一些有趣的文章。正如Jim提到的,一个重要的点是finalizer只会运行一次。


9

该对象直到再次变得不可达之前不会被回收。

根据JavaDoc,finalize()将不会再次被调用。


7
如果你仔细阅读API描述,你会发现finalizer可能会使对象再次可达。该对象直到再次不可达才会被丢弃,但是finalize()方法只会被调用一次。

实际上,finalizer 确实使对象通过根引用变得强可达,从对象被发现不可达到其finalizer运行的时间之间。 在此期间,如果被发现为不可达的对象成为对某些其他对象仅存活的引用,那么在运行finalizer或通过其他方式使该引用无效之前,该其他对象将无法被回收。 - supercat

3

是的,这就是为什么你不应该使用finalizers(其中之一)。

有一个引用集合被用来做这件事。我会查找并在这里发布它,但我认为它是PhantomReference。

没错,PhantomReference

幽灵引用对象,在收集器确定其引用可能被回收后入队。 幽灵引用通常用于以比Java终结机制更灵活的方式安排临死清理操作。


不,这就是为什么不要编写非常糟糕的终结器的原因(如果没有足够的其他原因)。 - Tom Hawtin - tackline

3
它实际上会进行另一次检查,以确保没有更多的引用指向该对象。由于第二次检查将失败,因此您最终不会释放该对象的内存。

由于finalize仅针对任何给定对象调用一次,因此下一次通过时,当它没有引用时,它将直接释放内存而不调用finalize。有关finalization的一些很好的信息,请单击此处


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接