【问题标题】:Garbage collection: Initial marking and concurrent marking垃圾回收:初始标记和并发标记
【发布时间】:2014-05-18 16:47:44
【问题描述】:

用于 Java 中的 Concurrent-Mark-Sweep 垃圾收集器;我不清楚这两个阶段有什么不同。为什么需要并发标记?初始标记没有找到所有活体吗?

【问题讨论】:

  • 这是一种尝试最小化 GC 必须停止应用程序的时间的方法。
  • 那么在初始标记阶段只有一些对象被惊吓并随后标记,其余的在并发阶段被扫描和标记?
  • 你把事情想得太简单了。 GC 不只是为了好玩而做同样的事情 3 次。
  • “初始标记”是什么意思?
  • @meriton,这是 CMS 垃圾收集器的第一阶段

标签: java garbage-collection


【解决方案1】:

使用CMS,即所谓的三色标记算法来标记活体。

  • 白色 - 未标记
  • 灰色 - 对象已标记,但未处理其出站引用
  • 黑色 - 标记对象并处理所有出站引用

标记从可到达的对象变灰开始,当没有更多的灰色对象可用时,它被认为已完成。

CMS 中的并发标记仅在旧空间中标记。所以旧空间之外的所有引用都是根引用

他们是

  • 可用的局部变量是线程堆栈
  • 从年轻空间到老空间的参考

由于只有旧空间适合并发标记,所有堆栈和年轻空间都应该以 stop-the-world 方式进动。这构成了 CMS 的 initial-mark 阶段。

一旦initial-mark 完成,CMS 在旧空间中有许多灰色对象开始并发标记。在并发标记期间,如果应用程序线程修改了黑色对象,它们可能会恢复为灰色。卡片标记写入器屏障允许 CMS 跟踪修改。

CMS 终于再次暂停remark。 Remark 再次重新扫描堆栈和年轻空间并完成旧空间的标记(大多数可到达的对象已经是黑色的,因此标记相当快)。年轻空间和堆栈不被写入屏障跟踪,因此 CMS 必须重新扫描它们以找到对旧空间的新引用。

remark完成后,旧空间中只有黑白物体,可以继续扫地。

您可以在this article 阅读有关 CMS 收集器的更多详细信息。

【讨论】:

  • 感谢您的详细回复。您的文章说“卡表(请参阅卡标记写入屏障)用于识别旧空间中已修改的内存部分,但应再次扫描线程堆栈和新空间。”我认为胎面叠层上的物品是根源。因此,听起来,在重新标记期间,我们再次查看在并发标记期间修改的对象以查看它们是否仍然存在,然后我们再次扫描线程堆栈以形成一棵新树。这是正确的理解吗?
  • 我们不关心对象是否“还活着”。目标是找到无法到达的对象。如果某些对象在并发阶段变得不可访问,它们将保持未被检测到,直到下一个 CMS 周期。这种效果被称为“漂浮垃圾”
猜你喜欢
  • 2019-09-09
  • 2011-02-08
  • 1970-01-01
  • 2014-11-08
  • 1970-01-01
  • 2018-06-10
  • 2011-07-16
  • 1970-01-01
  • 2011-04-26
相关资源
最近更新 更多