Wrayの知识库 Wrayの知识库
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
首页
  • Java 基础
  • Java 集合
  • Java 并发
  • Java IO
  • JVM
  • Spring Framework
  • Spring Boot
  • Spring Cloud
  • Spring Security
  • MySQL
  • Redis
  • 计算机基础
  • 操作系统原理
  • Linux
  • MacOS
  • Windows
  • 系统工程与研究专题
  • AI 基础
  • 大模型基础
  • Prompt 工程
  • RAG 检索增强生成
  • Agent 智能体
  • AI 应用开发
  • AI 工程化
  • AI 安全与治理
  • AI 面试与设计题
  • 纸质书
  • 电子书
  • 学习课程
疑难杂症
GitHub (opens new window)
  • Java章节编写规范
  • Java基础

  • Java集合

  • Java并发

  • Java IO

  • JVM

    • JVM概述
    • JVM基础

    • 类加载机制

    • 运行时内存

    • 垃圾回收

    • 执行引擎与优化

    • 工具与问题排查

      • JVM参数
      • JDK命令行工具
      • jstack线程分析
        • 1. 生成线程转储
        • 2. 线程状态
        • 3. 排查死锁
        • 4. 排查线程池耗尽
        • 5. 排查 CPU 飙高
        • 6. 常见栈顶含义
        • 7. 阶段小结
        • 8. 线程状态判断表
        • 9. CPU 高定位流程
        • 10. Tips 快问快答
      • jmap与堆转储分析
      • jcmd与JFR
      • CPU飙高排查
      • 内存泄漏排查
      • 频繁Full GC排查
    • 调优实践与面试

目录

jstack线程分析

线程问题是 Java 线上故障中非常常见的一类。jstack 可以帮助我们查看 Java 进程中每个线程正在做什么。

# 1. 生成线程转储

jstack -l <pid> > thread.dump

建议连续抓取多次:

jstack -l <pid> > thread-1.dump
sleep 5
jstack -l <pid> > thread-2.dump
sleep 5
jstack -l <pid> > thread-3.dump

单次线程栈只是瞬时状态,多次对比才能看趋势。

# 2. 线程状态

常见线程状态:

  • RUNNABLE:正在运行或等待 CPU。
  • BLOCKED:等待进入 synchronized。
  • WAITING:无限期等待。
  • TIMED_WAITING:限时等待。
  • NEW:尚未启动。
  • TERMINATED:已结束。

注意:RUNNABLE 不一定真的在占 CPU,也可能在 native IO 中等待。

# 3. 排查死锁

jstack 能检测 Java 层面的死锁。

常见输出:

Found one Java-level deadlock:

死锁通常表现为:

  • 线程 A 持有锁 1,等待锁 2。
  • 线程 B 持有锁 2,等待锁 1。

修复思路:

  • 固定加锁顺序。
  • 减少嵌套锁。
  • 使用超时锁。
  • 拆分临界区。

# 4. 排查线程池耗尽

如果大量线程处于等待远程调用、数据库、锁或队列状态,可能导致线程池耗尽。

关注:

  • 线程名。
  • 线程池前缀。
  • 栈顶方法。
  • 是否大量相同调用栈。
  • 是否阻塞在外部资源。

线程名规范非常重要。没有清晰线程名,排查会很痛苦。

# 5. 排查 CPU 飙高

CPU 飙高时,jstack 要结合系统线程 ID 使用。

常见步骤:

  1. top -Hp <pid> 找到高 CPU 线程。
  2. 把线程 ID 转成十六进制。
  3. 在线程转储中搜索 nid=0x...。
  4. 查看对应 Java 调用栈。

# 6. 常见栈顶含义

如果栈顶是:

  • Object.wait:线程在等待通知。
  • Thread.sleep:线程睡眠。
  • Unsafe.park:常见于 Lock、线程池、队列等待。
  • Socket read:可能在等待网络数据。
  • JDBC 调用:可能等待数据库。
  • 正则相关方法:可能是复杂正则导致 CPU 高。

# 7. 阶段小结

jstack 是分析线程状态的核心工具。抓线程栈时要多次采样,结合 CPU、线程池、业务日志和请求时间线判断。线程栈不是答案本身,它是定位问题的证据。

# 8. 线程状态判断表

状态 常见含义 重点排查
RUNNABLE 运行中或 native 等待 是否高 CPU,栈顶是什么
BLOCKED 等 synchronized 监视器 锁持有者是谁
WAITING 无限等待 是否正常等待队列/条件
TIMED_WAITING 限时等待 sleep、park、超时等待
NEW 未启动 一般不常见
TERMINATED 已结束 dump 中少见

# 9. CPU 高定位流程

top 发现 Java 进程 CPU 高
  │
  ├─ top -Hp &lt;pid> 找高 CPU 线程
  │
  ├─ printf "%x\n" &lt;tid> 转十六进制
  │
  ├─ jstack -l &lt;pid> 抓线程栈
  │
  ├─ 搜索 nid=0x...
  │
  └─ 分析该线程栈顶方法

要连续抓取多次,如果同一线程一直停留在同一段代码,说明热点更可信。

# 10. Tips 快问快答

Q:BLOCKED 和 WAITING 有什么区别?

A:BLOCKED 通常是在等进入 synchronized;WAITING 是已经主动等待某个条件或通知。

Q:Unsafe.park 一定有问题吗?

A:不一定。线程池空闲、Lock 等待、队列等待都可能看到 park,要结合线程数量和业务状态判断。

Q:死锁一定能被 jstack 发现吗?

A:Java 层 monitor 死锁通常能发现,但数据库锁、分布式锁、外部资源等待不一定能直接识别为 deadlock。

Q:线程栈里看不到业务代码怎么办?

A:可能在 native、JIT 编译代码或采样时机不对,可以多次采样或使用 JFR/profiler。

上次更新: 2026/06/24, 16:03:01
JDK命令行工具
jmap与堆转储分析

← JDK命令行工具 jmap与堆转储分析→

Copyright © 2023-2026 Wray | 鄂ICP备2024050235号-1
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式