参考敲定期间对象(Reference to object during finalize)

2019-06-23 09:42发布

如果你的最终化通话过程中保存到当前对象的引用会发生什么? 例如:

class foo {
    ...
    public void finalize() {
        bar.REFERENCE = this;
    }
}

是对象垃圾回收,或不? 当您尝试访问会发生什么bar.REFERENCE以后呢?

Answer 1:

该物体是不是垃圾收集。 这是知道的“对象复活”。

你必须要小心,一旦终结被称为GC将不会再次调用它,像.NET可以将部分enviroments重新注册的终结,但我不知道关于Java



Answer 2:

如果你绝对必须复活的对象,这JavaWorld的文章建议创建一个新的实例,而不是复活实例正在最后敲定,因为如果即将完成的情况下变得符合回收再会简单地收集(终结不会被再次运行)。



Answer 3:

这种事情是为什么使用的原因finalize()一般不提倡。



Answer 4:

因为Java是一种安全的语言和平台,内存不释放。 另外相关的PhantomReference旨意不会在他们入队ReferenceQueue秒。 虚拟机将只调用finalize一次对一个对象。 有一个在JVM规范中的一个很好的状态图。

通常,如果你使用finaliser,你应该把被宣布为@Override protected void finalize() throws Throwable ,以免打扰API。 更妙的是使用守卫finaliser,在有效的Java第1版。

这种特殊的技巧喧腾(圣荷西水星的,反正)当一组在普林斯顿用它来构建定制ClassLoader从不受信任的代码。 尽管该规范已略有收紧(该Object构造函数执行完毕之前正常的finaliser可以称为-在J2SE 5.0中规定,在Java SE 6中实现),这仍然是一个问题领域。 如果你正在设计一个API,确保敏感的类不能子类,并保存自己的悲伤。



Answer 5:

finalize()方法可以明确地对被调用foo例如,或者它可以被垃圾收集当它试图回收由该对象所占用的存储被调用。

如果bar是一个有效的实例,它设置的REFERENCE场到foo实例。 从视垃圾收集器的角度来看,这会增加foo的引用计数。

如果有异常内部抛出finalize()方法(例如,诸如一个NullPointerException由于barnull ),那么最终处理简单地终止。

NB正如其他人所指出的..你的榜样是绝对要避免的东西。



文章来源: Reference to object during finalize