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

时间:2017-10-19 13:50:17

标签: java oracle garbage-collection jvm-hotspot

我正在经历this link from oracle,只是想了解/确认一些观点。

1)对于CMS阶段 - 如果某个对象被标记为“Reachable”,那么这也意味着该对象是实时的?或者“直播”和“可达”不是“同一个”?

2)如果某些内容未被标记为默认的“可访问”,则无法访问?或者简单的原则“如果我没有将你标记为Reachable,那么你无法接触”?

2)即使没有明确提及,我假设在满足某个阈值(可能是某个时间戳或某个计数器)后,所有旧代(未标记为“可到达”)对象都被清除了?

我必须说链接非常好,但我想我是那些明确寻找“是/否”声明的读者之一。因此,如果有人能够对上述问题进行简单的肯定/否定确认,那么就会:)。

非常感谢。

2 个答案:

答案 0 :(得分:1)

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

“无法访问”的对象尚未死亡。它仍然存在于记忆中。但它没用,因为没有对象引用它。在这种情况下,Dead意味着“踢出老一代的空间”。

使用CMS GC,您必须使用JVM选项设置旧一代使用阈值,它具有默认值。内存使用率达到阈值后,它开始清除“无法访问”对象(现在它已从内存中释放)

答案 1 :(得分:0)

一般正式定义通俗地称为“live”,“not garbage”或“dead”,“garbage”仅考虑 reachability

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

  

每个对象都可以通过两个属性来表征:它可能是可达终结者可达无法访问,也可能是未终结可终结最终确定

     

可达对象是任何可以从任何活动线程继续计算中访问的对象。

     

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

     

无论如何都无法访问无法访问的对象。

     

未决定的对象从未调用过终结器。

     

finalized 对象已自动调用其终结器。

     

finalizable 对象从未调用过终结器,但Java虚拟机最终可能会自动调用其终结器。

所以¹,可以表示“实时”而无法访问表示“死”或“垃圾”而¹,无法访问意味着无法访问并且标记可到达的对象是测试不可达性的最直接方式。

¹只是因为你说你喜欢“是”或“不是”的答案

第3点无法回答“是”或“否”,因为没有“清洁”这样的事情。

未完成的对象由特殊列表引用。如果这些对象只能通过此特殊引用访问,那么它们将被排队以进行最终化,从而将它们变为 finalizable 。这些对象尚未无法访问

请注意,JVM会优化此步骤,因为大多数对象实际上并不需要最终确定。如果某个类从finalize()继承java.lang.Object方法或者具有空finalize()方法,则会将其视为“简单终结器”,并且此类的实例不会添加到首先是未完成的对象。这同样适用于finalize()方法,其中包含对另一个简单终结器的super.finalize()调用。

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

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

另一种选择是压缩,其他仍然可到达的对象被移动到无法访问的对象的位置。 复制将把所有可到达的对象移动(也称为复制)到新的内存区域,使整个源区域可用于新的分配。

所有替代品的共同之处在于他们没有对垃圾进行任何“清理”操作。即使作为空闲记忆的一部分,它们的记忆仍将包含之前的任何内容,直到被实际占用并因此被另一个物体覆盖。