JEP 344:G1 的可中止混合收集
概述
如果 G1 混合回收可能会超过暂停目标,则使其可中止。
非目标
使 G1 中的所有暂停均可中止。
动机
G1 的目标之一是满足用户为其收集暂停提供的暂停时间目标。G1 使用一种高级分析引擎来选择在收集期间要完成的工作量(这部分基于应用程序的行为)。此选择的结果是一组称为 收集集 的区域。一旦确定了收集集并开始了收集,那么 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%,并且仅在使用可选收集集部分的混合收集时才会产生。
-
在使用可选收集集部分的混合收集期间,原生内存使用量也可能增加。这是因为在此混合收集期间,必须跟踪指向可选部分区域的一些额外的传入指针。