Java 应用中一种典型的CPU 持续使用率高的问题

在 Java 应用中, 由于各种设计问题, 编码问题, 或者配置问题都有可能导致 CPU 一直在高位运行, 那么如何找到这些代码或者配置呢? 有没有什么通用的方法?

一般来说, 在 Linux 系统上使用 perf 命令, 画出火焰图, 通常都能找到问题所在. 如果运行的 JDK 中没有符号表, 会导致采集的栈中 Java 部分都是内存地址, 不能看到具体的方法名.

如果使用 asyc-profiler, 生成火焰图, 通常都能找到 CPU 占用率比较高的栈.

如果 CPU 持续在固定的使用率, 那么有更简洁的方法找到问题的根源, 这里就举一个这样的例子. 如下图所示, 一个 cluster 里面的应用有部分 server 持续的 CPU 使用率大概在25%, 50%, 75%, 100%:
cpu.png

为什么会集中在这些使用率的数值呢? 我们可以看到有部分server 的 CPU 使用率大概在10%以下, 这些都是正常的, 另外我们可以确认这些 server 分配了4个 CPU, 那么如果有线程持续占有一个 CPU core, 那么大概会导致整体升到25%, 以此类推, 如果占有4个, 那么就会导致100%.

如果我们首先能找到这些线程, 然后在看到它们在干什么, 那么我们就找到了问题所在. 所以第一步找到这些线程. 使用 htop 命令, 我们可以看到有些线程持续使用 CPU 在高位, 并且获得了它们的线程 native ID.
cpu3.png

接着我们获得 Java 应用的 thread dump, 就可以确定是什么代码导致持续占用 CPU 的问题了.
image004_png.png

标签: none

添加新评论