2

据我所知,CMS 收集器收集老年代,它与 ParNew 收集器(用于收集年轻代)一起工作。对我来说,要清楚地理解 CMS 的工作原理并不容易,但这是我的看法:

1) 初始标记。寻找根参考。由于收集器是 oldgen 收集器,它应该只扫描老年代。

2) Concurrent-Mark 找到所有根引用后,就该开始并发标记了。从第一阶段标记的对象可传递到达的所有对象都在该阶段标记。

3) 并发预清理 gc 查看 CMS 堆中的对象,这些对象在我们在前一个并发标记阶段进行并发标记时由年轻代的提升或新分配更新或由突变器更新。[请确认1 这个阶段的唯一目的是完成下一个阶段必须完成的部分工作(备注)?2) 有一些进程正在查看在并发标记阶段更改了哪些引用。请告诉我我对这两个项目是否正确]

4) 备注 gc 停止世界,然后查看 CMS 堆中的对象,这些对象在我们进行并发预清理时由年轻代的提升或新分配更新或由 mutators 更新。

但是今天看到这篇文章

初始标记在初始标记期间,CMS 应收集所有根引用以开始标记旧空间。这包括:来自线程堆栈的引用、来自年轻空间的引用。来自堆栈的引用通常被收集得非常快(小于 1ms),但是从年轻空间收集引用的时间取决于年轻空间中对象的大小。通常初始标记在年轻空间收集后立即开始,因此伊甸园空间是空的,只有存活对象位于幸存者空间之一。幸存者空间通常很小,年轻空间收集后的初始标记通常需要不到毫秒的时间。但是,如果在 Eden 已满时开始初始标记,则可能需要很长时间(通常比年轻空间收集本身更长)。一旦触发了 CMS 收集,JVM 可能会等待一段时间让年轻收集发生,然后才会开始初始标记。JVM 配置选项 –XX:CMSWaitDuration= 可用于设置 CMS 在开始初始标记之前等待年轻空间收集的时间。如果您想避免长时间的初始标记暂停,您应该将此时间配置为比应用程序中年轻集合的典型周期更长。

备注大部分标记与应用程序并行完成,但可能不准确,因为应用程序可能会在标记期间修改对象图。并发标记完成时;垃圾收集器应该停止应用程序并重复标记,以确保所有可到达的对象都标记为活动的。但是收集器不必遍历整个对象图;它应该只遍历自标记开始以来修改的参考(实际上是自开始预清洁阶段以来)。卡片表(参见卡片标记写屏障)用于识别旧空间中内存的修改部分,但应再次扫描线程堆栈和年轻空间。 通常remark阶段的大部分时间都花在扫描年轻空间上。如果我们在评论开始之前在年轻空间中收集垃圾,这个时间会短得多。我们可以指示 JVM 在 CMS 备注之前始终强制进行年轻空间收集。使用 JVM 参数 –XX:+CMSScavengeBeforeRemark 启用此选项。即使年轻空间是空的,remark 阶段仍然需要扫描 old space 中的修改引用,这通常需要接近正常年轻收集暂停的时间(由于在年轻收集期间完成的 old space 扫描类似于 remark 所需的扫描)。

http://blog.griddynamics.com/2011/06/understanding-gc-pauses-in-jvm-hotspots_02.html

不明白为什么 CMS 需要扫描年轻代。为什么老年代垃圾回收需要它?

4

2 回答 2

2

Java 堆分为两部分,它们是独立收集的:老空间和年轻空间。

要收集任一空间,您需要找到空间外的所有入站引用。他们是:

  • 堆栈中的局部变量
  • 嵌入到 JIT 编译的代码块中的文字
  • 来自另一个空间的所有引用

老收集应该扫描年轻空间和年轻收集应该扫描旧空间没有区别。

卡表写屏障用于不扫描每个年轻集合的整个旧空间(只有一小部分旧空间包含指向年轻空间的链接,写屏障有助于跟踪该区域)。

但是年轻空间没有卡表,所以老集合应该扫描整个内存范围。

PS我是你引用的文章的作者,你可以在我的博客上找到更多与GC相关的文章

于 2013-12-21T07:42:52.763 回答
2

您可能有具有循环引用的类,例如类 A 具有对类 B 的引用,而 B 具有对 A 的反向引用。如果您有属于这些类的对象 a 和 b,并且相互引用,则 gc 必须删除它们当您从“外部”删除对它们的最后引用时。当然,对于包含更多元素的参考循环,情​​况可能会复杂得多。所以 gc 必须检查哪些元素可以从某个根目录访问,哪些元素被引用但不可访问,应该被收集。

现在,如果你有,在你的代码的某个地方

Object a=new A(new B(new C(new D())))

在分配 a之前,构造函数可能需要一些时间。但是您不希望 gc 删除新创建的 D,只是因为 C 的构造函数需要一段时间才能运行,并且a还没有被分配。因此,您还需要扫描年轻代,以捕获太年轻而无法从堆中引用的对象。

于 2013-12-20T17:55:57.270 回答