java如何排查cpu飙高问题

100 阅读2分钟

在 Java 里排查 CPU 飙高问题,可按以下步骤进行:

1. 定位高 CPU 进程

首先要找出占用 CPU 过高的进程 ID(PID)。在 Linux 系统下,可使用top命令。

top

执行该命令后,系统会实时显示各个进程的资源使用情况。按P键能按 CPU 使用率对进程进行排序,从而快速定位到 CPU 使用率高的 Java 进程。记住该进程的 PID。

2. 定位高 CPU 线程

确定 Java 进程的 PID 后,要找出该进程里占用 CPU 过高的线程。使用top -Hp <PID>命令,其中<PID>是前面找到的 Java 进程 ID。

top -Hp <PID>

此命令会显示该 Java 进程下所有线程的 CPU 使用情况。同样按P键按 CPU 使用率排序,记住高 CPU 使用率线程的 ID。

3. 将线程 ID 转换为 16 进制

在获取高 CPU 线程的十进制 ID 后,需将其转换为十六进制,因为 Java 的线程栈信息里线程 ID 是十六进制表示的。使用以下命令进行转换:

printf "%x\n" <TID>

这里的<TID>是高 CPU 线程的十进制 ID。

4. 获取 Java 线程栈信息

使用jstack命令获取 Java 进程的线程栈信息,将其输出到文件中以便后续分析。

jstack <PID> > thread_dump.log

<PID>是 Java 进程的 ID。

5. 在线程栈信息中定位问题线程

thread_dump.log文件里搜索步骤 3 中得到的十六进制线程 ID,就能找到该线程对应的栈信息。通过分析栈信息,可了解该线程正在执行的方法和代码位置,进而定位问题根源。

6. 分析线程栈信息

常见的 CPU 飙高原因及对应的线程栈特征如下:

  • 死循环:线程栈里会有某个方法不断被调用,没有退出的迹象。
  • 锁竞争:可能会看到多个线程在等待同一个锁,出现java.lang.Thread.State: BLOCKED的状态。
  • IO 阻塞:线程可能处于WAITINGTIMED_WAITING状态,等待 IO 操作完成。

7. 使用工具辅助分析

除了上述的手动分析方法,还可以使用一些工具来辅助排查问题,例如:

  • VisualVM:这是一个可视化的工具,能实时监控 Java 进程的 CPU、内存、线程等使用情况,还可以进行线程 dump 和分析。