
top 找出 Java 进程 PID 后,为什么 top -H 显示的线程 ID 和 jstack 里的 nid 对不上
因为 top -H 默认显示的是 Linux 线程的十进制 TID(Thread ID),而 jstack 输出里 nid=0x... 是十六进制的 native thread ID。直接比对会漏掉真凶。
- 用
printf "%x\n" <tid></tid>把top -H看到的十进制 TID 转成小写十六进制,再和jstack输出里的nid=0x7f8a对照 - 注意:JDK 8u60+ 默认开启
-XX:+PrintGCDetails类日志不会干扰线程 ID,但若用了-XX:+UseContainerSupport(如 Docker),top显示的 CPU 可能被容器限制器压低,实际线程仍在狂转 -
jstack <pid></pid>必须由与 Java 进程同用户执行,否则可能只看到 “Unable to open socket file” 错误
如何快速从 jstack 输出里定位高 CPU 线程的调用栈
别通读 —— 高 CPU 线程大概率处于 RUNNABLE 状态,且栈顶是本地方法或密集计算逻辑,比如 HashMap.get、String.indexOf、synchronized 块内死循环、或 Unsafe.park 缺失导致自旋锁没退出。
- 先用
grep "java.lang.Thread.State: RUNNABLE" jstack.log -A 10提取所有可运行线程栈 - 再过滤常见热点模式:
grep -E "(at java|at sun|at com\.yourcompany|synchronized|while \(true\)|for \(.*;;\)" - 特别留意
Locked ownable synchronizers:下为空(说明没锁竞争)但线程仍在跑,极可能是纯 CPU 密集型逻辑,比如 JSON 序列化/反序列化、正则反复匹配、Base64 编解码未复用Encoder
为什么 jstack 看不到某些线程,或者显示 state: RUNNABLE 却没栈帧
两种典型情况:线程正在执行 JNI 方法(如 Netty 的 epoll_wait、Log4j2 的异步日志刷盘),或刚创建还没开始执行 Java 字节码(比如 new Thread().start() 后瞬间抓栈)。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- JNI 方法不会出现在 Java 栈中,
jstack只显示java.lang.Thread.State: RUNNABLE+ 一行at java.base/java.lang.Thread.sleep(Native Method)这类占位符 - 此时需结合
perf top -p <pid></pid>(需安装perf)看真正耗 CPU 的 native 符号,比如epoll_wait、memcpy、malloc - 如果应用用了虚拟线程(JDK 21+),
jstack默认不显示它们 —— 必须加-XX:+UnlockDiagnosticVMOptions -XX:+PrintVirtualThreads启动参数才能在日志里看到调度痕迹
避免 jstack 本身加剧问题的实操细节
jstack 会触发 JVM 全局 safepoint,对高并发应用可能造成几十毫秒 STW,尤其在 GC 频繁时容易误判为“卡顿”。不能反复高频执行。
- 单次采集足够:用
jstack -l <pid> > jstack_$(date +%s).log 2>&1</pid>保存完整上下文,包括锁信息(-l关键) - 别在生产环境用
jstack -F(强制 dump)—— 它会尝试挂起线程,可能引发服务雪崩,仅限进程已假死且无响应时兜底使用 - 如果应用启用了 ZGC 或 Shenandoah,
jstack仍安全;但用 G1 且堆超 32GB 时,dump 可能卡住数秒,建议提前用jcmd <pid> VM.native_memory summary</pid>辅助排查内存分配热点
真实线上问题往往不是单一线程作祟,而是多个线程在争抢同一把锁、或共享对象频繁 hash 冲突,这时候 nid 对得上只是起点,得顺着锁 ID(locked )和哈希表扩容逻辑往回查。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










