问题描述
我听说在Joshua Bloch的书中写道,如果我们重写finalize方法,分配和内存集合可能增加到430倍。
对我来说很清楚内存集合可以工作得更慢,因为gc需要额外的迭代才能释放内存。
但为什么可以增加分配阶段?
我已经搜索了原始声明:
所以这不是一般性陈述,但只是一个证据报告,表明其背后有一种模式,而不是数字是可重复的。当使用不太平凡的对象或更多的对象时,这个因素可能会改变。
当然,这些成本取决于如何实现最终化。在HotSpot中,将通过调用方法,每次创建一个带有不平凡的 finalize()
方法的对象。
这可能意味着比分配两个对象而不是一个对象成本高得多。这些 Finalizer
实例将被强连结,这对于防止收集 Finalizer
实例本身是必要的,并且它们具有对构造对象的引用。换句话说,无论初始对象分配的本地性如何,新对象都将转义,从而阻碍大量后续优化。
当它来破坏,回收一个普通的物体是没有任何操作的。不会采取任何行动,事实上,不可能对无法访问的对象执行任何操作,因为它无法访问。只有通过访问 当然,将不采取行动与任何其他行动进行比较可能导致任意因素。绝对数量为2,400ns,对于涉及排列对象并通知另一个线程轮询队列的操作是合理的。 I have heard that in Joshua Bloch book written that allocation and memory collection might be increased to 430 times if we override finalize method. It is clear for me that memory collection can work slower because additional iteration requred for gc to free memory. But why allocation phase can be increased? I have searched for the original statement: So this isn’t a general statement, but just a report of evidence that suggests that there is a pattern behind it, not that the number is reproducible. This factor is likely to change when using not-so-trivial objects or just a lot more of them. Of course, these costs depend on how finalization is actually implemented. In HotSpot, an instance of This might imply much more costs than just allocating two objects instead of one. These When it comes to "destruction", reclaiming an ordinary object is a no-op. No action will be taken and, in fact, it is impossible to do anything with the unreachable object, as it is unreachable. Special reachability states can only be encountered by having a reachable Of course, comparing "no action" with any other action can lead to arbitrary factors. The absolute number was 2,400ns, which is reasonable for an action that involves enqueuing an object and notifying another thread to poll the queue. 这篇关于如果我们重写finalize方法,为什么可以增加分配阶段?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! Reference
对象才能遇到特殊可达性状态,例如上面提到的 Finalizer
对象,它持有引用特定对象(而对象没有通过任何其他普通引用遇到,然后, Reference可以被排入队列,之后(其中一个)终结器线程(s)可以采取适当的行动。
Finalizer
will be created by calling the Finalizer.register
method every time an object with a non-trivial finalize()
method is created.Finalizer
instances will be strongly linked, which is necessary to prevent the collection of the Finalizer
instances themselves, and they have a reference to the constructed object. In other words, regardless of how local the object allocation initially was, the new object will escape, hindering lots of subsequent optimizations.Reference
object, like the Finalizer
object mentioned above, which holds a reference to the particular object (while the object wasn’t encountered through any other ordinary reference. Then, the Reference
object can be enqueued, after which (one of) the finalizer thread(s) can take the appropriate action.