Garbage-First垃圾收集器是如何工作的?

48

有人可以解释一下 G1 垃圾收集器是如何工作的吗?我还没有找到任何全面易懂的描述。

谢谢


它是平台特定的,因此会有所不同。 - Gordon
3个回答

46

收集器将堆分成一些固定大小的区域,并跟踪这些区域中的活动数据。它保留了一组指针,即“已记住的集合”,指向区域内外。当需要进行垃圾回收时,它首先收集具有较少活动数据的区域(因此称为“垃圾优先”)。通常,这意味着在一个步骤中收集整个区域:如果指向该区域的指针数量为零,则不需要对该区域进行标记或清除操作。

对于每个区域,它跟踪各种描述收集时间的度量。您可以给它软实时约束暂停时间,然后它尝试在受到约束的时间内尽可能多地收集垃圾。

有关G1的JavaOne演讲以及一些相关文章:


36

这个JavaOne 2012新的演讲中也很好地解释了G1垃圾回收器:G1 Garbage Collector Performance Tuning [youtube], [PDF]。

他们从介绍CMS和G1,它们之间的比较开始,然后解释了G1的分析和调优。

G1的特点:

  • 固定大小的区域 - 堆划分为区域(1Mb - 32MB,约2000个,由VM确定)。
  • Eden、Survivor和OldGen表示为逻辑区域集合
  • 活动对象被疏散从一个区域到另一个区域

典型的G1堆可能如下所示:

A typical G1 heap may look like:

以下是每个G1阶段的概述:

1. 年轻代回收

1.1 年轻代阶段 - Minor GC

  • 疏散 - Stop-The-World并行Minor GC,其中活动对象从年轻代疏散到Survivor区域(tenuring)或OldGen区域(晋升)。
  • 统计 - 根据每个区域的统计信息和应用程序设置的暂停时间目标,确定下一次Young GC的eden/survivor空间大小。G1估计下一个YoungGC需要多少时间。
  • 调整大小 - G1现在可以轻松地缩小/调整eden/survivor区域。

1.2 年轻/初始标记

  • GC young initial-mark 是OldGen集合的一个初始标记阶段,与YoungGC集合并行执行。这个初始标记是一个并行的并发标记过程。

2. Old Gen Collection

2.1 Initial Mark - 参见 1.2.

2.2 GC remark

  • 一个停止-全球暂停,同时标记活动对象
  • 会计 - 对于每个区域,在标记时,G1正在跟踪该区域的存活性(每个区域有多少对象是活动的)和引用该区域(Remembered Set),这告诉G1在该区域进行收集需要多长时间。
  • 回收空区域

2.3. GC pause (mixed)

  • 选择具有低存活性的区域并收集其中一些。因此,我们首先收集“垃圾”。
  • 这些区域的实际收集与下一个Young GC同时进行,因此没有单独的暂停来收集OldGen。因此,GC pause (mixed)是YoungGen和Old Gen的部分混合集合。
  • 在GC暂停(mixed)结束时,老年代区域中可能会有一些垃圾,这将根据未来的存活性、暂停时间目标和未使用区域的数量进行收集。

3. Full GC

请注意,G1旨在尽可能避免Full GC。从Java 7u40开始,G1中的FullGC暂停未经过优化,实现为单线程操作。使用G1时,请尽量避免Full GC-如果您看到任何FullGC暂停,您的GC设置可能需要进行调整。

资源


3
我发现Oracle的网页对于解释这些概念非常有帮助,易于理解且不过长。您可以访问此页面了解更多相关信息。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接