我听说 Joshua Bloch 书中写到,如果我们重写 Finalize 方法,分配和内存收集可能会增加到 430 倍。
我很清楚,内存收集的速度可能会变慢,因为 gc 需要额外的迭代来释放内存。
但是为什么分配阶段可以增加呢?
最佳答案
我查了一下原文:
On my machine, the time to create and destroy a simple object is about 5.6 ns. Adding a finalizer increases the time to 2,400 ns. In other words, it is about 430 times slower to create and destroy objects with finalizers.
因此,这不是一般性陈述,而只是一份证据报告,表明其背后存在某种模式,而不是表明该数字是可重复的。当使用不那么简单的对象或更多的对象时,这个因素可能会改变。
当然,这些成本取决于最终确定的实际实现方式。在 HotSpot 中, Finalizer
的实例将通过调用 Finalizer.register
创建每次创建具有重要 finalize()
方法的对象时都会调用该方法。
这可能意味着比只分配两个对象而不是一个对象要高得多的成本。这些 Finalizer 实例将被强链接,这对于防止 Finalizer 实例本身的收集是必要的,并且它们具有对构造对象的引用。换句话说,无论对象分配最初有多本地化,新对象都会逃逸,从而阻碍大量后续优化。
当谈到“销毁”时,回收一个普通对象是无操作的。不会采取任何操作,事实上,无法对无法访问的对象执行任何操作,因为它无法访问。特殊的可达性状态只能通过可到达的 Reference
对象来遇到,例如上面提到的 Finalizer
对象,它保存对特定对象的引用(而该对象不是通过任何其他普通引用遇到。然后,Reference
对象可以排队,之后(其中一个)终结器线程可以采取适当的操作。
当然,将“不采取行动”与任何其他行动进行比较可能会导致任意因素。绝对数为 2,400 纳秒,这对于涉及将对象入队并通知另一个线程轮询队列的操作来说是合理的。
关于java - 为什么如果我们重写 Finalize 方法可以增加分配阶段?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41378606/