Java - 并发标记扫描中的标记/未标记对象GC

Java - 并发标记扫描中的标记/未标记对象GC

问题描述:

我正在通过this link from oracle并试图了解/确认一些观点。Java - 并发标记扫描中的标记/未标记对象GC

1)CMS阶段 - 如果一个对象被标记为“可达”,这也意味着该对象是活的?或者“Live”和“Reachable”不是“独一无二”?

2)如果某些东西没有标记为“Reachable”,那么默认情况下,Unreachable?或者简单的原则“如果我没有标记你为Reachable,你无法接近”? 2)即使没有明确提及,我假设在达到某个阈值(可能是某个时间戳或某个计数器)之后,所有旧一代(不标记为“可达”)对象都被清除?

我必须说,这个链接是相当不错的,但我想我是那些明确寻找“是/否”声明的读者之一。所以如果任何人都可以通过简单的是/否来确认上面的问题,那么它会做:)。

非常感谢。

如果一个对象没有被标记。这是“无法到达”

“无法到达”的对象还没有死。它仍然存在于记忆中。但没有任何对象可以参考它,因此没用。在这种情况下,Dead的意思是“踢出旧世代空间”。

对于CMS GC,您必须使用JVM选项设置旧一代使用率阈值,它具有默认值。之后的内存使用量达到阈值,开始扫出“无法接通”的对象(现在是从内存中释放)

+0

“无法到达的对象还没有死” - 我不确定这是正确的,因为在该链接上它说“未标记对象==死对象” – ha9u63ar

+0

@ ha9u63ar“死”有很多含义我想。我的话“死”意味着摆脱记忆。文档的“死”比我的死更大意义 –

+0

如果我愿意,我会对你的答案做一个小修改:) – ha9u63ar

什么是俗称的“活”,“不是垃圾”或“死”的一般正式的定义, “垃圾”只考虑可达性

比较与The Java® Language Specification, §12.6.1. Implementing Finalization

每个对象都可以由两个属性来表征的:它可以是可达终结可达的,或可达,并且它也可以是未确定可终结终定

A 可达对象是可以从任何活动线程进行任何潜在的持续计算中访问的任何对象。

A 终结器可达可以从某个可终结对象通过一些引用链到达对象,但不能从任何活动线程到达对象。

一个无法达到无法通过任何方式达到目标。

安装未终止对象从未自动调用终结器。

A 定稿对象自动调用了终结器。

A 可终结对象从来没有自动调用终结器,但Java虚拟机最终可能会自动调用终结器。

所以¹,可达的意思是“活的”,可达手段“死”或“垃圾”和¹,不是可达意味着是可达和标记可达对象是测试不可达性的最直接方式。


¹只是因为你说你喜欢的答案,在“是”或“否”


第三点不能用“是”或“否”的回答来看,因为没有“清洁”这样的东西。

未终止对象被特殊列表引用。如果这些对象只能通过这个特殊的引用到达,他们将被列入终结,这使得它们可以终结。这些对象不是无法达到呢。

请注意,JVM优化了这一步,因为大部分对象实际上并不需要完成。如果一个类从java.lang.Object继承finalize()方法,或者有一个空的finalize()方法,则它被认为是“平凡的终结器”,并且该类的实例首先不会被添加到未定义的对象列表中。这也适用于finalize()方法,该方法由唯一的super.finalize()呼叫到另一个平凡的终结器组成。

因此无法访问对象是其终结器已被执行或具有“琐碎终结器”的对象。在任何一种情况下,都不需要采取任何行动来“清除”它们。这些物体不像街道上的垃圾,必须拾取并放入垃圾箱。内存位置仍然包含对象处于活动状态时所包含的内容,但未使用。实际上,在垃圾收集器检测到它之前它已经没有使用。

结束对象生命周期的关键是让内存可用于新的分配。 CMS的扫描意味着通过内存并将不可达对象的地址添加到空闲内存列表。该阶段直接在标记之后开始,但是如CMS中的C所示,同时

另一种方法是压缩其中,其他仍然可到达的对象移动到不可访问对象的位置。并且复制将移动(又名副本)全部可达对象到新的内存区域,使整个源区域可用于新的分配。

所有替代方案的共同之处在于,他们没有对垃圾做任何事情来“清理”垃圾。即使是空闲内存的一部分,它们的内存仍然会包含之前的内容,直到被实际占用并因此被另一个对象覆盖。