为什么在 Java 9 G1 工作约 6 小时后,即使实际负载没有增加,性能也会下降?

46

我将一个实例(2 vCPU、2GB RAM,负载约为4k req/sec)从最新的Java 8切换到Java 9。一开始一切都很好,CPU使用率与之前相同。然而,大约6小时后,CPU消耗增加了4%(从21%增加到25%),原因不明。我没有流量激增,没有增加内存消耗,没有度量变化(我对代码中的每个方法都进行了计数)。没有任何变化。

我让这个实例保持不变约12小时,期望它会恢复正常。但是什么也没变。它只是继续消耗更多的CPU。

top命令显示该实例的Java服务器进程比通常有更多的CPU波动。我最近读到G1不适合高吞吐量。所以我得出结论,原因可能在于G1。

我使用以下命令重新启动了实例:

java -XX:+UseParallelGC -jar server-0.28.0.jar

经过约20小时的监控,一切都和以前一样。CPU消耗量与许多天前相同,保持在21%的水平。

Java 9部署后的CPU使用情况(6小时尺度):

enter image description here

7小时+ 12小时“未更改”后的CPU增加(7天尺度):

enter image description here

-XX:+UseParallelGC之后的CPU(24小时尺度):

enter image description here

那么我的问题是 - 这是G1的预期行为吗?其他人是否看到了类似的情况?

Ubuntu 16.04 x64

java version "9"
Java(TM) SE Runtime Environment (build 9+181)
Java HotSpot(TM) 64-Bit Server VM (build 9+181, mixed mode)

编辑 2019年03月01日

尝试在Java 10.0.2上使用G1在同一台服务器上运行:

java version "10.0.2" 2018-07-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.2+13)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.2+13, mixed mode)

服务器重启后,G1的CPU消耗比UseParallelGC高40%。


3
你有没有在那个时间点(6小时尺度)看到GC日志?如果能排除对GC的疑虑并确定确切原因,将会增强信心。 - Naman
6
是的,如果没有日志记录,这几乎是不可能完成的任务(除非猜测)。 - Eugene
1
我没有进行任何调整。所有部署都是默认设置。只需运行 java -jar server.java 即可。 - Dmitriy Dumanskiy
6
这是生产环境,所以我不想冒险。根据我的经验,在生产环境中使用GC日志记录通常风险较小,只要不打开成本高昂的跟踪级别功能。需要注意的是,日志会占用磁盘空间并导致IO,如果您的IO设备延迟高,则可能会出现问题,但这些问题是相当可预测的。 - the8472
1
我觉得这个问题是无法回答的。JVM运行时并不是确定性的。许多事情可能会发生 - 其中一些甚至可能与GC无关,即使根据您的启动选项看起来像是相关的。 - Amir Afghani
显示剩余5条评论
1个回答

2
请注意,GC调优极大地依赖于环境,因此没有魔法配方。我们曾遇到过与G1非常相似的问题。默认情况下,它似乎不太适合REST端点(这只是我在直接邻居中经历的情况)。帮助我的是尝试使用GC标志,如此处所述。对我们来说,最大的改进来自于-XX:G1NewSizePercent=25和-XX:MaxGCPauseMillis=50。G1也会随着时间而自动调整自己,因此最大GC暂停限制对所有其他参数都有重要影响。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接