方案一:仅使用 JDK 原生工具(零依赖,无需额外安装)
JDK 自带工具无需额外下载,是 Linux 下排查 Java CPU 高的基础方案,核心流程为「定位进程→定位线程→定位代码→排查根因」。
步骤 1:定位高 CPU 的 Java 进程
| 操作 | 命令 | 关键说明 |
|---|---|---|
| 查看系统高 CPU 进程 | top |
按P键按 CPU 占用率从高到低排序,找到%CPU≈100% 的进程,记下进程 PID |
| 验证是否为 Java 进程 | jps -l |
列出所有 Java 进程(PID + 主类 /jar 包路径),确认第一步的 PID 对应你的应用 |
步骤 2:定位进程内高 CPU 的线程
Java 进程 CPU 高通常是单个 / 少数线程导致,需进一步缩小范围:
| 操作 | 命令 | 关键说明 |
|---|---|---|
| 查看进程内线程 CPU 占用 | top -Hp [进程PID] |
按P排序,找到 CPU 占比最高的线程,记下线程 tid(LWP 列数值) |
| 线程 ID 转为 16 进制 | printf "%x\n" [线程tid] |
jstack 日志中线程 ID 为 16 进制,示例:printf "%x\n" 12345 → 输出3039(小写即可) |
步骤 3:抓取线程栈,定位具体代码行
线程栈(thread dump)是定位问题代码的核心:
# 导出线程栈到日志文件(方便查看)
jstack [进程PID] > thread_dump.log
# 打开日志并搜索16进制线程ID
vim thread_dump.log
# 在vim中输入 /[16进制tid] 搜索(比如 /3039)
- 重点看搜索结果中RUNNABLE状态的线程(表示线程正在运行);
- 堆栈信息会明确显示:
类名.方法名(文件名:行号)(如com.xxx.service.UserService.queryUser(UserService.java:58)),这就是 CPU 高的核心代码位置。
步骤 4:辅助排查 ------ 验证是否为频繁 GC 导致
若代码无明显异常,需排查 GC 问题:
# 每秒输出一次GC统计,持续监控
jstat -gc [进程PID] 1000
- 关注
FGC(Full GC)列:若每秒多次 Full GC,大概率是内存泄漏导致 GC 频繁占用 CPU; - 关注
YGCT/FGCT列:GC 总耗时过高也会拉高 CPU。
步骤 5:常见根因及解决方法
| 根因 | 典型特征 | 解决方法 |
|---|---|---|
| 死循环 / 无限循环 | 线程状态一直RUNNABLE,对应代码有while(true)无退出条件 |
修复循环退出条件,增加超时 / 中断判断 |
| 频繁 Full GC(内存泄漏) | jstat看 FGC 频繁,Arthas dashboard 看 GC 耗时高 |
排查内存泄漏(如静态集合无限添加、未关闭连接),调整 JVM 内存参数 |
| 锁竞争 | 线程状态多为BLOCKED,上下文切换频繁 |
优化锁粒度(局部锁代替全局锁),改用非阻塞容器(如ConcurrentHashMap) |
| 低效算法 / 代码 | 热点方法是嵌套循环、字符串拼接等 | 优化算法(如 HashMap 替代遍历),用StringBuilder拼接字符串 |
方案二:使用 Arthas 工具(新手首选,可视化分析)
Arthas 是阿里开源的 Java 诊断工具,无需改代码、无需重启应用,可视化程度高,新手能快速定位问题,核心优势是「跳过手动转 16 进制、直接输出问题代码、生成火焰图」。
步骤 1:安装并启动 Arthas
# 下载Arthas包
curl -O https://arthas.aliyun.com/arthas-boot.jar
# 启动Arthas(会列出所有Java进程,输入对应序号回车)
java -jar arthas-boot.jar
步骤 2:核心排查命令(直接定位问题)
| 命令 | 作用 | 关键说明 |
|---|---|---|
thread -n 3 |
显示 CPU 占用最高的 3 个线程 | 直接输出线程状态、执行的类 / 方法 / 行号,无需手动转 16 进制,新手优先看这个 |
dashboard |
实时监控 CPU、内存、线程、GC | 全屏可视化展示,按q退出,快速判断整体状态(如 GC 是否频繁) |
profiler start |
启动 CPU 热点采样 | 采样 30 秒左右即可,不要采样过久 |
profiler stop |
停止采样并生成火焰图 | 输出 HTML 文件路径,将文件下载到本地,浏览器打开后,红色块就是 CPU 占比最高的方法 |
步骤 3:常见根因及解决方法
与「方案一」的步骤 5 完全一致,找到问题代码后针对性优化即可。
总结
- 核心排查逻辑:无论用哪种方案,都遵循「定位 Java 进程 → 定位高 CPU 线程 → 找到问题代码 → 针对性优化」;
- JDK 原生工具:零依赖,适合无外网 / 无法安装工具的环境,需手动转 16 进制、分析日志;
- Arthas 工具:新手友好,可视化强,
thread -n 3可直接定位问题代码,profiler火焰图能直观看到 CPU 热点方法。