垃圾优先垃圾回收器如何工作?

2022-09-01 00:00:21

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

谢谢


答案 1

收集器将堆拆分为固定大小的区域,并跟踪这些区域中的实时数据。它保留了一组指针 - “记住的集合” - 进出该区域。当认为有必要使用 GC 时,它会首先收集实时数据较少的区域(因此,“垃圾优先”)。通常,这可能意味着一步收集整个区域:如果进入某个区域的指针数为零,则不需要对该区域进行标记或扫描。

对于每个区域,它会跟踪各种指标,这些指标描述了收集它们所需的时间。您可以为它提供关于暂停时间的软实时约束,然后尝试在该受限时间内收集尽可能多的垃圾。

有JavaOne关于G1的讨论和关于这个主题的文章:


答案 2

G1在这个新的JavaOne 2012会议中也得到了很好的解释:G1垃圾收集器性能调优[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 年轻阶段 - 次要GC

  • 疏散 - 停止世界平行次要GC,其中活体从年轻一代疏散到幸存者区域(紧张)或OldGen区域(促销)。
  • 会计 - 下一个年轻GC的伊甸园/幸存者空间的大小是根据每个区域的统计数据和应用程序设置的暂停时间目标确定的。G1估计下一个YoungGC需要多少时间。
  • 调整大小 - G1 现在可以轻松缩小/调整伊甸园/幸存者区域的大小。

1.2 年轻/初始标记

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

2. 老世代收藏

2.1 初始标记 - 见1.2。

2.2 GC 备注

  • 一站式世界暂停,并发标记活动对象
  • 记帐 - 对于每个区域,在备注期间,G1 正在跟踪该区域的生存性(每个区域中有多少个对象处于活动状态),以及对该区域的引用(记住集) - 这告诉 G1 在此区域上进行收集需要多长时间。
  • 回收的空区域

2.3. GC 暂停(混合)

  • 选择低活力的地区并收集其中一些。因此,我们正在收集“垃圾优先”。
  • 这些区域的实际收集与下一个年轻GC同时执行,因此OldGen的收集没有单独的暂停。因此,GC暂停(混合)是YoungGen和old Gen的一部分混合集合。
  • 在GC暂停(混合)结束时,旧一代区域中可能会留下一些垃圾,这将根据未来的宜居性,暂停时间目标和未使用区域的数量在以后收集。

3. 全气相色谱

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

资源