要排查Java程序导致CPU飙高的问题,可以按以下步骤操作:
1. 定位高CPU进程
- Linux/Mac: 使用
top命令查看CPU占用最高的进程,记录PID。top -c - Windows: 任务管理器 → 性能 → CPU → 找到Java进程PID。
2. 定位高CPU线程
-
Linux/Mac:
top -H -p <PID> # 查看该进程的所有线程 ps -eLf <PID> # 列出线程及CPU占用 ps -eLo pid,lwp,pcpu,cmd | grep <PID> | sort -k3 -nr | head -10 # 列出该进程下最耗 CPU 的线程 -
记录CPU占用高的线程的 十进制TID(如
11567),转为 十六进制(0x2d2f,备用)。 -
Windows:
- 使用
Process Explorer(微软官方工具),查看线程的CPU占用。
- 使用
3. 获取线程堆栈
使用 jstack 导出线程堆栈信息:
jstack -l <PID> > thread_dump.log
4. 分析高CPU线程堆栈
在 thread_dump.log 中搜索上一步得到的 十六进制TID:
"main" #1 prio=5 os_prio=0 tid=0x00007f4c6400a800 nid=0x2d2f runnable [0x00007f4c6a8f0000]
分析该线程的堆栈,重点关注:
RUNNABLE状态的线程(通常在执行计算或循环)。- 阻塞操作(如死循环、锁等待)。
5. 使用诊断工具(可选)
-
Arthas(推荐):
# 启动Arthas java -jar arthas-boot.jar <PID> # 查看最忙的线程 thread -n 3 # 监控方法耗时 monitor -c 5 *ClassName* methodName -
VisualVM 或 JConsole:
实时监控线程状态、CPU使用情况。 -
Async-Profiler:
生成火焰图,定位热点代码:./profiler.sh -d 30 -e cpu -f flamegraph.html <PID>
6. 常见原因及修复
-
死循环:
while (true) { // 无退出条件或条件错误 }修复:添加退出条件或线程休眠。
-
高计算任务:
- 检查算法复杂度(如大文件处理、密集计算)。
- 修复:优化算法或异步拆分任务。
-
阻塞操作:
- 锁竞争(如
synchronized、ReentrantLock)。 - 数据库/网络阻塞。
修复:减少锁粒度或用并发工具(如ConcurrentHashMap)。
- 锁竞争(如
-
频繁GC:
- 检查GC日志,内存泄漏导致频繁Full GC。
jstat -gcutil <PID> 1000 10 # 监控GC状态修复:优化对象创建,排查内存泄漏。
7. 复现与压测
- 在开发环境复现问题(用相同参数或数据集)。
- 使用 JMeter 或 wrk 进行压测,验证修复效果。
关键命令总结
| 步骤 | 命令/工具 | 作用 |
|---|---|---|
| 定位进程 | top / 任务管理器 | 找高CPU的Java进程PID |
| 定位线程 | top -H -p <PID> / Process Explorer | 找高CPU线程TID |
| 导出堆栈 | jstack -l <PID> > dump.log | 保存线程堆栈 |
| 线程分析 | grep 'nid=0xHEXTID' dump.log | 定位问题线程堆栈 |
| 诊断工具 | Arthas、VisualVM、Async-Profiler | 实时监控与热点分析 |
通过以上步骤,90%以上的CPU飙高问题可以准确定位并解决。如果是第三方库/框架的问题,需升级版本或修改配置。
1612

被折叠的 条评论
为什么被折叠?



