java - 调试 JVM 中 CPU 使用率 100%

标签 java debugging jvm

有一个 Java 应用程序偶尔会开始利用所有可用的内核,导致 GC 不足并因 OOM 而崩溃。该应用程序相当复杂。它使用 Akka Streams、Kafka、Etcd,并具有用于指标报告的内置 HTTP 服务器。我添加了-XX:+CrashOnOutOfMemoryError创建核心转储,但它们没有帮助,它们显示无法分配内存的线程,但需要的是实际占用所有 CPU 的线程。有什么指南或想法可以帮助您了解正在发生的情况吗?

该应用程序在 Linux 上的 OpenJDK 11 上运行,并通过 cgroup 分配了 3 个核心。堆大小设置为 3Gb,初始堆大小为 1.5Gb,它使用 G1,无需任何调整。

UPD:崩溃时heap_lock既不由 Activity 线程也不由 GC 线程持有,并且最后 10 个 GC 事件基本上未能释放任何内存。

最佳答案

即将耗尽内存的 JVM 大部分时间都花在垃圾收集上。

具体来说,垃圾收集的成本与使用的内存成正比,其频率与释放的内存成反比。因此,当内存使用率接近 100% 时,垃圾收集开销趋于无穷大……这实际上是导致 JVM 因 OutOfMemoryError 中止的原因(并不是说 JVM 在尝试释放内存时无法释放更多内存,而是因为集合与释放的内存完全不成比例)

您可以通过检查 JVM 指标(特别是垃圾收集开销)来检查这是否是导致 CPU 问题的原因。您可以使用 JConsole 检查 JVM 指标或任何其他 JMX 客户端。

如果 JVM 指标确认大部分 CPU 时间都花在 GC 上,那么修复内存问题就足够了。要了解如何解决内存问题,请参阅 How to identify the issue when Java OutOfMemoryError?

关于java - 调试 JVM 中 CPU 使用率 100%,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57260002/

相关文章:

java - java中可变参数的最大参数数量是多少?

java - 为什么这里不需要 return 语句?

java - 覆盖具有通用返回类型的方法

java - 从 jpanel 添加/删除 jlabel

c# - BackgroundWorker 中未处理的异常

android - 看似无用的安卓调试环境

javascript - 使用 Gradle 在 IntelliJ 中使用多个源集的 2 个项目 Unresolved 依赖关系

java新手问题: richer java subprocesses

java - 嵌套异常是 java.lang.NoSuchMethodError : javax. ws.rs.ClientErrorException.validate

javascript - napchart.com 是如何构建的