启用 ZGC 时出现“分配停滞”

hve*_*iga 5 java garbage-collection java-11 zgc

zgc我正在测试 11中包含的新垃圾收集器java,因为它承诺非常低的延迟。我们的应用程序是一个实时服务,每秒创建和销毁许多对象,并且它在多线程环境中使用akka.

zgc通过传递选项-XX:+UnlockExperimentalVMOptions -XX:+UseZGC和启用gc日志来启用时,我们可以在日志中看到许多类似于以下的消息:

[2020-05-20T18:05:36.563+0000][63.851s][info ][gc] Allocation Stall (Main-akka.remote.default-remote-dispatcher-6) 11332.231ms
[2020-05-20T18:05:36.563+0000][63.851s][info ][gc] Allocation Stall (Main-akka.remote.default-remote-dispatcher-26) 9898.046ms
[2020-05-20T18:05:36.563+0000][63.851s][info ][gc] Allocation Stall (Main-io-blocking-dispatcher-52) 12133.240ms
[2020-05-20T18:05:36.563+0000][63.851s][info ][gc] Allocation Stall (Main-akka.actor.default-dispatcher-54) 9002.299ms
[2020-05-20T18:05:36.563+0000][63.850s][info ][gc] Allocation Stall (Main-io-blocking-dispatcher-50) 12134.218ms
[2020-05-20T18:05:36.563+0000][63.850s][info ][gc] Allocation Stall (Main-akka.actor.default-dispatcher-46) 12132.540ms
[2020-05-20T18:05:36.563+0000][63.851s][info ][gc] Allocation Stall (Main-akka.actor.default-dispatcher-56) 8072.664ms
Run Code Online (Sandbox Code Playgroud)

几秒钟后,JVM 退出,没有给出任何原因。我们正在奔跑openjdk-java-11。关于如何开展这项工作有什么建议吗?

Tay*_*lor 4

分配停顿意味着线程正在请求堆,但没有可用的堆,因此请求线程正在阻塞。

确保您有足够的 gc 线程设置。JDK 可能无法检测核心计数,特别是在使用 Docker 时,gc 线程的默认值就源自 Docker。请参阅https://wiki.openjdk.java.net/display/zgc/Main#Main-SettingConcurrentGCThreads

如果您的 CPU 利用率在这些时间内较低,则另一个迹象表明您需要更多 GC 线程。

一般来说,启用hugepages可以提高 ZGC 的性能。 https://wiki.openjdk.java.net/display/zgc/Main#Main-EnablingLargePagesOnLinux

另外,您可能只需要更多的堆。

编辑添加:可能还值得确保您使用的是 jdk 和操作系统的最新补丁版本。