在《java性能权威指南》一书中,对吞吐量垃圾收集器和cms垃圾收集器的cpu利用率进行了比较,如下所示:
吞吐量收集器在运行时(默认情况下)将消耗机器上100%的可用cpu,因此在测试期间cpu使用情况的更准确表示如图5-2所示。大多数情况下,只有应用程序线程在运行,占用了总cpu的25%。当gc启动时,100%的cpu被消耗。因此,实际的cpu使用量类似于图中的锯齿形模式,即使测试期间的平均值报告为直线虚线的值。
当后台线程与应用程序线程同时运行时,并发收集器中的效果不同。在这种情况下,cpu的图形可能如图5-3所示。
应用程序线程首先使用总cpu的25%。最终它为cms后台线程创建了足够的垃圾;该线程还消耗了整个cpu,使总数达到50%。当cms线程完成时,cpu使用率下降到25%,以此类推。请注意,没有100%的cpu峰值周期,这有点简单:在cms年轻一代收集期间,会有非常短的峰值达到100%的cpu使用率,但是这些峰值足够短,我们可以在本次讨论中忽略它们。
我知道当吞吐量垃圾收集器运行时,它会停止所有应用程序线程,而cms垃圾收集器会与其他应用程序线程同时运行,但我不明白为什么当吞吐量收集器启动时,它会使用整个cpu周期,并将cpu利用率提高到100%,但当cms收集器启动时,它会留下50%的cpu未使用?是否有任何东西阻止cms收集器使用所有可用的cpu资源?
2条答案
按热度按时间wsewodh21#
我喜欢这种与现实几乎没有联系的虚构图形;那么
CMS
已弃用并在中删除java-14
,仅供参考。我也不是一个gcMaven,但我喜欢在不同的代码实现(尤其是在Shenandoah
作为免责声明。想想看:当你停止这个世界,把每一根线都拖到一根绳子上,去做那件事
GC
,你的首要任务是要做得很快,非常快。由于找出什么是垃圾并将其移动到清除区域是一项cpu受限的任务,因此您需要尽可能多的cpu和尽可能多的线程来执行该任务。所以呢CMS
以及其他收藏家STW
暂停将使cpu达到最大值,这样工作完成得更快。由于吞吐量收集器根本没有任何并发暂停,这些峰值可能更明显。相比之下,有些阶段CMS
是concurrent
,因此cpu利用率在图形上可能不太明显。还有一个有趣的现象是,某些垃圾收集器会故意让应用程序运行得更慢。它们可以为“mutator”(应用程序)线程提供较低的优先级,并从gc实现本身提升这些线程。
Shenandoah
调用这个“步调”,当分配率对于gc线程来说太高而无法处理时,它就会这样做。但我要重复一遍,这是一个虚构的图表,对cpu利用率的真正理解和正确结论是非常重要的。
nnvyjq4y2#
由于cms收集器同时执行一些工作,因此它的设计不是使用所有可用的系统资源,而是更像一个后台任务。这在更大程度上适用于g1和zgc。
由于并行采集器是同步的,所以它被设计为使用所有可用的系统资源来尽快完成工作。