是什么让终结者如此昂贵?

时间:2012-07-17 14:01:07

标签: java finalizer

来自Effective Java:

  

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

是什么让终结者如此昂贵?

3 个答案:

答案 0 :(得分:5)

关键的区别在于终结者方法的存在,无论它做什么。一旦GC具有可最终确定的对象,就必须更加努力地使所有的内务处理正确。它必须将它们标记为可最终化,将它们保存在池中,运行最终化,检查它们是否在此之后复活,通过最终化代码处理所有类型的多线程问题,等等。

在GC的年轻一代中可以看到最明显的差异:在一个乐观的,并非完全罕见的情况下,GC可以归结为单个操作:将指针递减到第一个可用的内存地址。对于终结者,这是上面概述的整个过程。

答案 1 :(得分:5)

http://www.ibm.com/developerworks/java/library/j-jtp01274/index.html

从上面的链接中提取

具有终结器的对象(具有非平凡的finalize()方法的对象)与没有终结器的对象相比具有显着的开销,应该谨慎使用。可完成对象的分配速度较慢,收集速度较慢。在分配时,JVM必须使用垃圾收集器注册任何可终结对象,并且(至少在HotSpot JVM实现中)可完成对象必须遵循比大多数其他对象更慢的分配路径。同样,可完成对象的收集速度也较慢。在可回收可完成对象之前,它至少需要两次垃圾收集周期(在最好的情况下),并且垃圾收集器必须做额外的工作来调用终结器。结果是花费更多的时间来分配和收集对象以及对垃圾收集器施加更多压力,因为无法访问的可终结对象使用的内存保留的时间更长。再加上终结器不能保证在任何可预测的时间范围内运行,甚至完全没有运行这一事实,你可以看到相对较少的情况,最终确定是正确使用的工具。

答案 2 :(得分:0)

当您进行基准测试时,您可能会对对象的使用寿命进行基准测试。

对象存在于其使用寿命之外,基本上在最后一个程序引用消失和垃圾收集例程(在不同的线程中运行)检测到分离的对象之间存在时间延迟。添加终结器时,对象的“使用寿命”现在会延长,直到垃圾收集检测到分离的对象,并在JVM运行完成方法之后。

它不是100%,因为存在一个终结方法,终结会增加这么多时间,很多时候都在等待垃圾收集线程唤醒并最终偶然发现你的分离对象(并决定对此采取行动)。