Java - CMS 与 G1 垃圾收集器

Java - CMS vs G1 garbage collector

cms 和 g1 垃圾收集器有什么区别让 g1 更好?

大部分地方都说这是因为在G1中,heap是分region的 然后区域集合被标记为 young/old 代 并且 gc 在少数区域而不是整个堆上运行。我正在尝试进一步了解这一点并提出更多问题:

  1. 当young gc运行时(stop the world)它运行在所有的新生代区域 这意味着整个堆的年轻部分和年轻一代的不少区域。 那么它在时间上是否与CMS相同?

  2. 增量压缩 - 混合集合 - 现在这是我认为 G1 有优势的地方,因为 整个堆的并发标记不断发生,并且有混合的 gc 周期运行 所有年轻区域+少数旧区域(首先是大多数垃圾)。所以它不断地从中清除垃圾 老年代也是如此,而不是等待 Full gc 发生。正确吗?

以上几点是否正确?还有哪些其他差异使 g1 更好?

我会补充一些我知道的原因。

  • 暂停目标时间

您可以有效地指示 G1 尽量在暂停目标时间内完成其工作。在内部,它将根据之前 collections 的统计数据选择要处理的区域数量。它也会因此调整区域的大小。你不能用 CMS.

做到这一点
  • 记住集

CMS 只有一个 card table 内部结构,这意味着它需要始终被完全扫描。另一方面,G1 使用 Remembered Sets,它的尺寸更小,可以(快速)判断哪些 other 区域需要作为当前区域的一部分进行扫描.

  • 混合Collections

是的,G1 可以扫描年轻的 加上 旧的一小部分 - 称为 mixed collections(您可以通过标志配置大小),但是这个意味着它比完全扫描旧的要快得多。

  • 碎片

很可能是早期 G1 左右开始理论工作的最大触发因素,至少我与 CMS 一起工作的“老”队友说这是一个最大的痛苦。 CMS 根本不做任何 compaction。当 objects 无法移动到 old generation 时(因为那一代的“差距”太小了)——一切都停止了, space 需要继续努力。这变得非常昂贵并且花费了很多时间。另一方面,每个 G1 循环在移动时进行压缩 objects 并留下空白区域。


可能还有很多我还不知道的其他原因。