Cao的JEP草案旨在在禁用并发优化时提高G1垃圾收集器的吞吐量,并减少总体CPU使用率。 他之所以想这样做,是因为G1垃圾收集器的写后障碍目前比并行和并发标记清除等传统垃圾收集器要复杂。 原因是G1支持并发优化,这需要后屏障将脏卡添加到每个线程的脏卡队列中,并确保适当的内存可见性。 因此,G1的后屏障在Java代码中的吞吐量和CPU使用率上具有明显的开销。
曹写道:“并发优化可同时构建记住的集合,以减少收集暂停期间的卡片扫描工作。 但是,并发优化对某些类型的工作负载的好处有限。 示例包括面向吞吐量的工作负载和已调整的工作负载,以最大程度地减少了旧集合。 对于这些情况,G1可以通过简化后置障碍并禁用并发细化来实现更好的性能。”
会发生什么变化?
Java增强建议草案将为G1引入吞吐量后写入障碍。 因此,如果通过-XX:G1ConcRefinementThreads=0
禁用了并行优化,则编译器和解释器将为写pf = q
发出简化的后屏障:
if (p and q in same region) -> exit
if (q is NULL) -> exit
if (*card(p) == DIRTY) -> exit
*card(p) = DIRTY
G1会扫描映射到收集集之外区域的脏卡以及收集集内区域的记忆集,从而确保正确性。
总体而言,这将减少处理脏卡和JIT编译器的编译工作所涉及的全部工作量。 此外,减少记忆集的大小并且不使用每线程脏卡队列,从而减少了内存占用。
还请参见:
备择方案
曹建议,实现吞吐量写后障碍的另一种方法是:
if (p and q in same region) -> exit
if (q is NULL) -> exit
*card(p) = DIRTY
但是,他写道,这种方法的基准表明,与拟议的障碍相比,该替代障碍几乎没有性能差异。 提议的屏障与默认的写入后屏障具有更多相似性,这使得有可能实施进一步的增强,例如在默认屏障和吞吐量屏障之间动态切换。”
还请参见:
其他观察
在某些用例中,如果禁用并发优化和吞吐量写入后障碍,则很难达到较小的暂停时间目标。 曹提供了一个示例,该示例具有大堆和相当一部分长寿命对象的工作负载。 他认为此类情况不在他的建议范围内,因为它们通常会启用并发限制。
有关更多信息,请在此处阅读有关G1吞吐量写后障碍的JEP草案 。
翻译自: https://jaxenter.com/java-jep-draft-throughput-post-write-barrier-g1-161449.html