一句话总结
CPU飙高排查遵循定位进程 → 定位线程 → 导出堆栈 → 分析原因的流程。常用工具:top、jstack、Arthas。常见原因:死循环、频繁GC、线程竞争、正则回溯。
初级理解
排查步骤:
1. 定位进程:top 命令找到CPU占用最高的Java进程PID
2. 定位线程:top -Hp <PID> 查看该进程下最耗CPU的线程TID
3. 转换进制:printf "%x\n" <TID> 将线程ID转为十六进制
4. 导出堆栈:jstack <PID> | grep <十六进制TID> -A 20
一句话总结:top → top -Hp → printf → jstack。
中级深入
常见原因:
• 代码问题:死循环、正则回溯、复杂算法
• 频繁GC:内存泄漏或对象创建过快
• 线程竞争:大量线程自旋或上下文切换
Arthas实战:
# 一键查看最忙线程
thread -n 3
# 实时面板
dashboard
# 查看方法耗时
trace com.example.UserService getUserById
注意:jstack导出堆栈时,RUNNABLE状态说明正在执行,BLOCKED状态说明在等待锁。
高级拓展
Arthas高级用法:
# 线程死锁检测
thread -b
# 方法执行耗时统计
monitor -c 10 com.example.UserService getUserById
# 反编译查看字节码
jad com.example.UserService
# 热更新class文件
redefine /path/to/UserService.class
JVM参数调优:
# 增加GC日志
-Xloggc:/path/to/gc.log -XX:+PrintGCDetails
# 调整线程栈大小
-Xss512k
面试加分项:能说出Arthas高级用法、JVM参数调优、线上问题排查经验,说明你有丰富的运维经验。
实战场景
场景:订单服务CPU飙高排查
# 1. 定位进程
top
# PID: 12345, %CPU: 95.0
# 2. 定位线程
top -Hp 12345
# TID: 12378, %CPU: 90.0
# 3. 转换进制
printf "%x\n" 12378
# 输出: 305a
# 4. 导出堆栈
jstack 12345 | grep 305a -A 20
# 发现卡在:
# at com.example.service.OrderService.createOrder(OrderService.java:56)
# 5. 分析代码:发现是死循环
# while(order.getStatus() != "PAUSED") {}
面试模拟
Q:如何快速定位Java应用的性能瓶颈?
A:1. top命令找CPU/内存占用高的进程;2. jstat观察GC频率;3. jstack导出线程堆栈分析阻塞点;4. jmap导出堆快照分析内存泄漏;5. Arthas在线诊断方法耗时。
Q:线上服务出现OOM如何排查?
A:1. 启动参数添加-XX:+HeapDumpOnOutOfMemoryError;2. 使用MAT打开.hprof文件;3. 查看Leak Suspects报告;4. 分析Dominator Tree找到占用内存最大的对象;5. 追溯GC Roots引用链定位泄漏代码。