如果Java的世代垃圾收集器遍历活动对象的图,那么他们如何知道要调用finalize()的对象? [英] If Java's generational garbage collectors traverse the graph of live objects, how do they know which objects to call finalize() on?

查看:65
本文介绍了如果Java的世代垃圾收集器遍历活动对象的图,那么他们如何知道要调用finalize()的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的理解是,诸如ParallelGC和G1之类的GC是世代"收集器.垃圾回收几乎是作为副产品发生的,因为您将所有活动对象移动到新的堆区域,而旧区域中剩下的任何内容都将被覆盖.除了Java需要在死对象上调用finalize()的部分之外,这种副产品"的解释很有意义.Java是否还在每个堆区域中保留了一个 all 对象的单独列表,它可以再次与活动对象进行比较?

My understanding is that GCs like ParallelGC and G1 are "generational" collectors. Garbage Collection almost happens as a byproduct, since you move all live objects to a new heap region and anything left in the old region will simply be overwritten. This "byproduct" explanation makes a lot of sense, except for the part where Java needs to call finalize() on the dead objects. Does Java also keep a separate list of all objects in each heap region that it can compare agains the live objects?

推荐答案

是的, GC 跟踪所有这些对象及其类型.

Yes, a GC keeps track of all these Objects and their types.

事实上,GC有一个专用阶段,仅处理以下特殊引用: WeakReference SoftReference PhantomReference 和人工的 Finalizer .有人称它为清理阶段,有人称其为参考处理" ;其中有 Pre-cleapup Post-cleanup 阶段.

As a matter of fact there is a dedicated phase for GCs that deals just with these special references: WeakReference, SoftReference, PhantomReference and the artificial Finalizers. Some call it Cleanup phase, some Reference Processing; as part of these there are Pre-cleapup and Post-cleanup phases.

但是想法是,当 GC 遇到这样的特殊"提示时,在标记阶段参考,它会关注这些.首先,它分别跟踪它们(想想:将它们注册在特殊的 List 中).当完成 mark 阶段(至少对于某些 GC 而言)时,它将在暂停状态下停止分析这些引用.其中一些使用起来并不那么复杂: WeakReference s和 SoftReference s是最简单的:如果 referent 是弱/软可及的,将其回收并将特殊事件发送到 ReferenceQueue . PhantomReference 几乎相同(java-8与9之间有区别,但不再赘述).

But the idea is that when a GC encounters such a "special" reference during the mark phase, it keeps an eye on these. First it tracks them separately (think: registers them in a special List). When the mark phase is done (at least for some GCs), it will analyze these references under a pause (stop-the-world). Some of them are not that complicated to work with: WeakReferences and SoftReferences are the easiest ones: if the referent is weakly/softly reachable, reclaim it and send a special event to the ReferenceQueue. PhantomReferences are almost the same (there is a diff between java-8 and 9, but will not go into details).

... Java需要在死对象上调用finalize()

... where Java needs to call finalize() on the dead objects

您就在这里.最丑陋的是 Finalizers ,主要是因为 GC 必须恢复它获得的死对象,因为它需要在实例上调用 finalize 该实例无法到达或死亡;但是GC无法回收它.因此, GC 首先恢复该对象,只是在下一个将对此实例起作用的周期中立即将其杀死.它不一定是 second ,它通常可以是第100个周期;但这必须是涉及此特定实例的第二个.

You are sort of right here. The ugliest one is Finalizers, mainly because a GC has to resurrect the dead Object that it got, since it needs to call finalize on an instance and that instance is unreachable, or dead; but the GC can't reclaim it. So a GC first revives the Object, only to kill it in the immediately in the next cycle that will work on this instance. It does not have to be the second, it could be the 100-th cycle in general; but it has to be the second that involves this particular instance.

这篇关于如果Java的世代垃圾收集器遍历活动对象的图,那么他们如何知道要调用finalize()的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆