jstack 工具详解与 Java 进程 CPU 过高标准化排查
·
一、jstack 工具说明
1. 工具作用
jstack 是 JDK 自带的JVM 线程堆栈分析工具,用于导出当前 Java 进程内所有线程的运行状态、调用栈、锁信息、线程状态,是定位 Java 性能问题的核心工具。
2. 主要使用场景
- Java 进程 CPU 占用过高(100%、800%+)
- 线程死锁、循环等待
- 服务夯死、接口不响应
- 线程过多、线程泄漏
- 代码死循环、高频计算
3. 常用标准命令
# 查看线程堆栈(基础)
jstack <PID>
# 显示额外锁信息(推荐生产使用)
jstack -l <PID>
# 进程僵死无响应时强制导出
jstack -F <PID>
# 导出堆栈到日志文件(排查必用)
jstack -l <PID> > jstack_$(date +%Y%m%d%H%M).log
二、Java 进程 CPU 过高 标准排查流程
步骤 1:找到 CPU 占用最高的 Java 进程 PID
top
- 查看 % CPU 列,找到占用最高的 Java 进程
- 记录 PID(例如:1688)
步骤 2:定位该进程内最耗 CPU 的线程 TID
top -H -p <PID>
# 示例:top -H -p 1688
- 显示该进程下所有线程
- 找到 % CPU 最高的线程,记录十进制 TID(例如:1702)
步骤 3:将线程 TID 转换为十六进制
jstack 中的线程 ID(nid)是十六进制,必须转换:
printf "%x\n" <线程TID>
# 示例:printf "%x\n" 1702 → 输出 6a6
- 得到 nid:
0x6a6
步骤 4:使用 jstack 导出完整线程栈
jstack -l 1688 > stack_1688.log
步骤 5:在堆栈日志中搜索对应线程
grep -i 'nid=0x6a6' stack_1688.log -A 30
-A 30显示后 30 行,展示完整调用链- 直接定位到高 CPU 线程的堆栈
步骤 6:分析堆栈定位问题代码
重点关注:
java.lang.Thread.State: RUNNABLE(高 CPU 几乎都是此状态)- 堆栈最下层的业务类、方法、行号,即为高 CPU 根源代码
三、线程堆栈关键字段解释
"Thread-1" prio=5 os_prio=0 tid=0x00007f... nid=0x6a6 runnable
java.lang.Thread.State: RUNNABLE
com.example.biz.UserServiceImpl.getUserList(UserServiceImpl.java:95) ← 问题代码行
- nid=0xXXX:操作系统线程 ID(十六进制)
- runnable:线程正在运行(高 CPU 核心状态)
- 堆栈自下而上:调用源头 → 上层逻辑
四、Java CPU 过高常见根本原因
while(true)死循环(最常见)- 递归无退出条件
- 高频序列化 / 反序列化、JSON 解析
- 正则表达式极端回溯(ReDoS)
- 大量循环计算、复杂逻辑
- GC 异常(可配合 jstat 进一步确认)
五、极简记忆口诀(方便背诵)
- top 找进程 PID
- top -H 找线程 TID
- printf 转十六进制
- jstack 导出线程栈
- grep 搜 nid 定位代码
- 看栈底行解决问题
更多推荐



所有评论(0)