Skip to content

JEP 344: Abortable Mixed Collections for G1 | G1 的可中断混合集合

摘要

如果 G1 混合收集可能超过暂停目标,则允许它们中止。

非目标

使 G1 中的所有暂停都可以中止。

动机

G1 的一个目标是在其收集暂停期间满足用户提供的暂停时间目标。G1 使用一个高级分析引擎来选择在收集期间要完成的工作量(这部分基于应用程序的行为)。这种选择的结果是称为 收集集(collection set)的一组区域。一旦收集集被确定并且收集开始,G1 就必须在不停止的情况下收集收集集中所有区域的所有活动对象。如果启发式选择了一个过大的收集集,而这种行为可能导致 G1 超过暂停时间目标,比如当应用程序的行为改变导致启发式基于“陈旧”的数据工作时。这种情况在混合收集中尤为明显,因为收集集经常可能包含过多的老年代区域。因此,需要一种机制来检测启发式是否反复为收集选择了错误的工作量,如果是这样,则让 G1 以步骤的方式逐步执行收集工作,并在每个步骤之后都可以中止收集。这样的机制将允许 G1 更频繁地满足暂停时间目标。

描述

如果 G1 发现收集集选择启发式算法反复选择了错误数量的区域,则切换到一种更增量化的混合收集方式:将收集集分为两部分,一部分是必需的,另一部分是可选的。必需部分包括 G1 无法增量处理的收集集的部分(例如,年轻代区域),但为了提高效率也可以包含老年代区域。这可能占预测收集集的 80% 左右。预测收集集剩余的 20%,这部分仅包含老年代区域,则形成可选部分。

G1 完成必需部分的收集后,如果有剩余时间,G1 将开始以更细粒度的级别收集可选部分。这部分可选收集的粒度取决于剩余的时间,最多可以细化到一次只收集一个区域。在完成可选收集集的任何部分的收集后,G1 可以根据剩余时间来决定是否停止收集。

随着预测再次变得更加准确,收集的可选部分会变得越来越小,直到必需部分再次包含整个收集集(即 G1 完全依赖其启发式算法)。如果预测再次变得不准确,那么下一次收集将再次包含必需部分和可选部分。

备选方案

  • 改进分析引擎和启发式算法,使它们不会做出错误的预测。尽管这本身是一个有趣的目标,但由于启发式算法依赖于之前的应用程序行为,因此不可能得到 100% 准确的启发式算法。然而,改进的启发式算法将自动减少对这种机制的需求。

  • 在预测方面始终使用“安全边际”。例如,如果预测返回 x,则始终使用 0.8 * x(即 20% 的安全边际)。这在大多数情况下可能有效,但当预测确实有效时,将导致性能次优,因为这意味着 G1 只会利用 80% 的暂停目标。

  • 重用现有的疏散失败机制来中止混合收集。这一方案已被拒绝作为替代方案,因为在中止时无法保证收集释放了任何区域。我们提出的机制通过在区域基础上回收收集集的空间来保证空间回收的进度,这是 G1 空间回收的粒度。

测试

实现中的各个 C++ 部分应该使用 C++ 单元测试进行测试。由于可中止的混合收集代码将成为 G1 垃圾收集器(GC)的一个组成部分,只需运行现有的测试即可测试这些代码。

风险与假设

  • 当将收集集分为必需部分和可选部分时,需要为可选收集集部分维护一些额外的数据。这会给 CPU 带来轻微的开销,小于 1%,并且仅在使用可选收集集部分的混合收集中产生。

  • 在使用可选收集集部分的混合收集中,本地内存的使用量也可能增加。这是因为在此混合收集期间,必须跟踪指向可选部分中区域的一些额外的传入指针。