我听说在Joshua Bloch的书中写道,如果我们覆盖finalize方法,分配和内存收集可能会增加到430倍。
对我来说很明显,内存收集可以更慢地工作,因为gc需要额外的迭代来释放内存。
但为什么分配阶段可以增加?
答案 0 :(得分:1)
我搜索了原始声明:
在我的机器上,创建和销毁一个简单对象的时间是关于的 5.6 ns。添加终结器可将时间增加到2,400 ns。换句话说,它是关于 使用终结器创建和销毁对象的速度要慢430倍。
因此,这不是一般性陈述,而只是一份证据报告,表明其背后有一种模式,而不是该数字是可重复的。当使用不那么重要的对象或只使用更多的对象时,这个因素可能会改变。
当然,这些成本取决于如何实际完成最终确定。在HotSpot中,每次创建具有非平凡finalize()
方法的对象时,都会通过调用Finalizer
方法创建Finalizer.register
的实例。
这可能意味着比分配两个对象而不是一个对象要多得多。这些Finalizer
实例将强烈链接,这对于阻止Finalizer
实例本身的收集是必要的,并且它们具有对构造对象的引用。换句话说,无论最初对象分配的本地化程度如何,新对象都将转义,阻碍了大量后续优化。
当涉及到“破坏”时,回收普通物体是无操作。不会采取任何操作,事实上,无法对无法访问的对象执行任何操作,因为它无法访问。只有拥有可访问的Reference
对象(如上面提到的Finalizer
对象)才能遇到特殊的可达性状态,该对象包含对特定对象的引用(而对象未通过任何其他普通引用遇到)然后,Reference
对象可以入队,之后(其中一个)终结器线程可以采取适当的行动。
当然,将“无动作”与任何其他动作进行比较可能会导致任意因素。绝对数量为2,400ns,这对于涉及将对象排队并通知另一个线程轮询队列的操作是合理的。