有效的Java第7项:避免使用终结器

时间:2014-10-15 11:54:26

标签: java garbage-collection finalizer effective-java

在这本神奇的书中,作者Josh Bloch提到:

"哦,还有一件事:使用终结器会有严重的性能损失。在我的机器上,创建和销毁简单对象的时间约为5.6 ns。添加终结器可将时间增加到2,400 ns。换句话说,使用终结器创建和销毁对象的速度要慢约430倍。"

我们有没有办法在java中删除和对象? 我以为我们可以简单地让对象超出范围或将它们重置为null。
我打算在我的机器上进行实验,这似乎是一个有趣的想法,但我是不确定如何删除和反对。

2 个答案:

答案 0 :(得分:2)

一旦你使引用变量引用null(假设最后一个引用)并且该变量超出其范围,那么该对象就有资格在下一个垃圾收集周期被垃圾收集。

答案 1 :(得分:2)

当一个对象不再有任何强有力的根引用时,它将不再存在;在大多数情况下,确切地说应该发生什么。但是,在某些情况下,对象会要求外部实体代表它做某事,可能会损害其他实体,以换取承诺让其他实体知道何时不再需要其服务。例如,"文件"对象可能会要求操作系统对文件进行独占访问;直到操作系统被告知不再需要这种访问,它将阻止其他人使用该文件。

如果一个做出这样一个承诺的对象被放弃并且根本就不复存在,那么外部实体将继续做任何被要求做的事情,这对其他人都是有害的,即使它的行为不再是对任何人都有好处。为避免这种情况,Java允许对象在GC注意到它们似乎已被放弃时请求通知。在对象不再存在之前,将给出这样的通知(即Finalize将在这些对象上调用),但除此之外没有真正的及时性保证。最终确定的对象然后可以通知任何和代表它的所有实体他们应该停止这样做。

Java的创建者可能期望终结器成为对象可以通知外部实体不再需要其服务的主要机制,但终结确实不能很好地工作。在许多情况下,AutoCloseablePhantomReference等其他机制会更好。