深入解析 JDK jstack 命令:线程分析的利器

news2025/5/9 17:21:21

你点赞了吗?你关注了吗?每天分享干货好文。

高并发解决方案与架构设计。

海量数据存储和性能优化。

通用框架/组件设计与封装。

如何设计合适的技术架构?

如何成功转型架构设计与技术管理?

在竞争激烈的大环境下,只有不断提升核心竞争力才能立于不败之地。

留言【我要晋级】,一对一指导,带你晋级。

引言

在 Java 应用开发中,线程问题(如死锁、CPU 占用过高、线程阻塞等)是常见的性能瓶颈和故障根源。JDK 工具 jstack 命令是分析和诊断 Java 线程状态的必备工具。

本文将从基础到实战,详细讲解 jstack 的使用方法、核心功能及常见问题的排查技巧,帮助你快速定位和解决线程相关问题。

一、jstack 是什么?

jstack 是 JDK 提供的一个命令行工具,用于生成 Java 虚拟机(JVM)的线程转储(Thread Dump)
线程转储是 JVM 中所有线程状态的快照,包含以下关键信息:

  • 线程的调用栈(Stack Trace)
  • 线程的状态(RUNNABLE、BLOCKED、WAITING 等)
  • 锁信息(持有的锁或等待的锁)
  • 线程优先级和所属线程组

通过分析线程转储,可以快速定位死锁、线程阻塞、CPU 占用过高等问题。

二、安装与基本使用

1. 环境要求

  • JDK 1.6+(建议使用与目标 Java 进程相同的 JDK 版本)
  • jstack 位于 JDK 的 bin 目录下(如 $JAVA_HOME/bin/jstack

2. 命令语法

jstack [options] <pid>          # 通过进程 ID 获取线程转储
jstack [options] <executable> <core>  # 分析核心转储文件
jstack [options] [server_id@]<remote server IP or hostname>  # 远程调试
常用参数:
  • -l:输出 详细的锁信息(如哪些线程持有锁,哪些在等待锁)
  • -F:强制生成线程转储(适用于进程无响应的情况)
  • -m:混合模式(显示 Java 和本地方法的堆栈帧)

三、实战:生成线程转储

1. 查找 Java 进程 ID

使用 jps 命令快速获取目标 Java 进程的 PID:

jps -l

2. 生成线程转储

jstack -l 12345 > thread_dump.txt  # 将输出重定向到文件

3. 强制生成转储(进程无响应时)

jstack -F -l 12345 > thread_dump_force.txt

四、线程转储分析指南

1. 线程状态解析

线程转储中的线程状态是分析问题的关键,常见状态如下:

  • NEW:刚创建的,还有调用 start() 之前的线程处在 NEW 状态上。此时线程与普通对象没区别,仅仅是堆中的一个线程对象而已。
  • RUNNABLE:正在运行,或者是具备运行条件,在运行队列中等待被 CPU 调度执行。如果线程长时间处在该状态下,说明线程运行时间长,或者一直没有CPU调度执行(线程饥饿现象)。
  • BLOCKED:线程在等待进入同步块或方法,本质就是在等待锁,例如被 synchronized 保护的代码块或方法。
  • WAITING:线程无限期等待其他线程的特定操作(如 Object.wait())。
  • TIMED_WAITING:线程在有限时间内等待(如 Thread.sleep(1000))。
  • TERMINATED:线程已终止,执行完 run 方法正常返回,或者抛出了运行时异常而结束,线程都会停留在这个状态。这个时候线程只剩下Thread对象了,没有什么用了。

2. 关键信息字段

"main" #1 prio=5 os_prio=0 tid=0x00007f8b4800e800 nid=0x1a03 waiting on condition [0x00007f8b50a0e000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x000000076b8a1c98> (a java.util.concurrent.locks.ReentrantLock$NonfairSync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireQueued(AbstractQueuedSynchronizer.java:870)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquire(AbstractQueuedSynchronizer.java:1199)
    at java.util.concurrent.locks.ReentrantLock$NonfairSync.lock(ReentrantLock.java:209)
    at java.util.concurrent.locks.ReentrantLock.lock(ReentrantLock.java:285)
    at com.example.MyService.doSomething(MyService.java:42)
  • 线程名称"main"
  • 线程 IDtid=0x00007f8b4800e800
  • 本地线程 ID(NID)nid=0x1a03(对应操作系统的线程 ID)。
  • 锁信息waiting for <0x000000076b8a1c98> 表示该线程正在等待某个锁。
  • prio:优先级,默认是 5

五、常见问题排查案例

常见现象:

CPU 使用率过高,响应慢

这种情况情况,需要在一次请求中进行多次 thread dump 文件的转储,做先后对比,如果 runnable 的线程前后差异大,说明系统属于正常情况,是服务器资源不够的问题,需要加大服务器资源。如果是在执行同一个方法,那就要去排查该方法的实现逻辑是否存在较大的问题,是否有优化的空间。

案例 1:死锁检测

死锁的主要表现是系统卡顿,无法响应用户的请求,进程的 CPU 占用率一般为零。

一般 JDK 5 以上,线程 Dump中可以直接报告出 Java 级别的死锁

步骤:

1、生成线程转储:jstack -l <pid>

2、搜索 deadlock 关键字:

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x00007f8b4800e800 (object 0x000000076b8a1c98, a java.lang.Object),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x00007f8b4800e800 (object 0x000000076b8a1c98, a java.lang.Object),
  which is held by "Thread-1"

3、根据提示修复代码中的锁竞争逻辑。

案例 2:CPU 占用过高

该情况下,一般表现为系统响应慢。

步骤:

1、使用 top 命令,确定占用 CPU 最高的进程ID(PID)。

2、生成线程转储:jstack -l <pid>

3、使用 top -H -p pid 查看该进程中,各线程的CPU 占用情况。

4、上述看到的 PID 其实就是线程 ID,但是是十进制的,使用 printf "%x\n" PID,输出 十六进制。

5、在线程转储中搜索该 十六进制的线程,定位到问题线程的堆栈:

"WorkerThread" #42 prio=5 os_prio=0 tid=0x00007f8b4800e800 nid=0x3039 runnable [0x00007f8b50a0e000]
   java.lang.Thread.State: RUNNABLE
    at com.example.MyService.cpuIntensiveMethod(MyService.java:100)

6、分析代码逻辑,优化高 CPU 消耗的操作。

7、如果分析代码无法找到高 CPU 的理由时,就需要在一次请求中进行多次 thread dump 文件的转储,做先后对比,如果 runnable 的线程前后差异大,说明系统属于正常情况,是服务器资源不够的问题,需要加大服务器资源。如果是在执行同一个方法,那就说明该方法是有较大可能存在问题,还需要再去分析代码是否有优化的空间。

案例 3:线程长时间阻塞

步骤:
  1. 查找处于 BLOCKEDWAITING 状态的线程。
  2. 分析锁的持有者和等待链:
"DB-Connection-Thread" #5 prio=5 os_prio=0 tid=0x00007f8b4800e800 nid=0x1a03 waiting for monitor entry [0x00007f8b50a0e000]
   java.lang.Thread.State: BLOCKED (on object monitor)
    at com.example.DatabaseService.executeQuery(DatabaseService.java:50)
    - waiting to lock <0x000000076b8a1c98> (a com.example.ConnectionPool)
  1. 检查代码中是否存在不合理的锁竞争或资源争用。

六、高级技巧与工具

1. 自动化分析工具

  • VisualVM:图形化工具,支持实时线程监控和转储分析。
  • FastThread:在线线程转储分析工具(https://fastthread.io/)。
  • IBM Thread and Monitor Dump Analyzer:用于复杂线程问题的分析。

2. 结合其他命令

  • jps:快速查找 Java 进程 ID。
  • jstat:监控 JVM 统计信息(GC、类加载等)。
  • jmap:生成堆转储(Heap Dump)。

七、注意事项

  1. 权限问题:确保执行 jstack 的用户有权限访问目标 Java 进程。
  2. 生产环境谨慎使用 -F:强制生成转储可能导致 JVM 暂停。
  3. 多次采样:对于偶现问题,建议多次生成线程转储进行对比分析。

八、总结

jstack 是 Java 开发者必须掌握的诊断工具,能够快速定位线程相关的问题。通过本文的学习,你已经掌握了以下技能:

  1. 生成和分析线程转储。
  2. 诊断死锁、CPU 占用过高、线程阻塞等常见问题。
  3. 使用高级工具优化分析效率。

架构设计之道在于在不同的场景采用合适的架构设计,架构设计没有完美,只有合适。

在代码的路上,我们一起砥砺前行。用代码改变世界!

如果有其它问题,欢迎评论区沟通。

感谢观看,如果觉得对您有用,还请动动您那发财的手指头,点赞、转发、在看、收藏。

高并发解决方案与架构设计。

海量数据存储和性能优化。

通用框架/组件设计与封装。

如何设计合适的技术架构?

如何成功转型架构设计与技术管理?

在竞争激烈的大环境下,只有不断提升核心竞争力才能立于不败之地。

留言【我要晋级】,一对一指导,带你晋级。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2338769.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【操作系统原理03】处理机调度与死锁

文章目录 大纲一.处理机调度概念与层次0.大纲1.基本概念2.三个层次3.七状态模型4.三层调度都对比与联系 二.进程调度的时机&#xff0c;切换与过程的调度方式0.大纲1.进程调度时机2.调度方式3.进程的切换与过程 三.调度器和闲逛资源1.调度器/调度程序2.闲逛进程 四.调度算法的评…

Quipus,LightRag的Go版本的实现

1 项目简介 奇谱系统当前版本以知识库为核心&#xff0c;基于知识库可以快构建自己的问答系统。知识库的Rag模块的构建算法是参考了LightRag的算法流程的Go版本优化实现&#xff0c;它可以帮助你快速、准确地构建自己的知识库&#xff0c;搭建属于自己的AI智能助手。与当前LLM…

使用 Vite 快速搭建现代化 React 开发环境

1.检查环境 说明&#xff1a;检测环境&#xff0c;node版本为18.20.6。 2.创建命令 说明&#xff1a;创建命令&#xff0c;选择对应的选项。 npm create vitelatest 3.安装依赖 说明&#xff1a;安装相关依赖。 npm i

PG数据库推进医疗AI向量搜索优化路径研究(2025年3月修订版)

PG数据库推进医疗AI向量搜索优化路径研究 一、医疗 AI 向量搜索的发展现状与挑战 1.1 医疗数据特征与检索需求 医疗数据作为推动医疗领域进步与创新的关键要素,具有鲜明且复杂的特征。从多模态角度看,医疗数据涵盖了结构化数据,如患者基本信息、检验检查报告中的数值结果;…

可穿戴经颅多通道直流电刺激产品测试总结

一 概念原理 tDCS 是一种非侵入性的神经调节技术&#xff0c;利用恒定、低强度直流电&#xff08;通常为 0 - 2mA&#xff09;通过电极作用于特定的大脑区域。其工作原理是通过调节神经元的膜电位&#xff0c;来增加或降低神经元兴奋性的特定区域&#xff0c;从而改变大脑运作。…

详解与HTTP服务器相关操作

HTTP 服务器是一种遵循超文本传输协议&#xff08;HTTP&#xff09;的服务器&#xff0c;用于在网络上传输和处理网页及其他相关资源。以下是关于它的详细介绍&#xff1a; 工作原理 HTTP 服务器监听指定端口&#xff08;通常是 80 端口用于 HTTP&#xff0c;443 端口用于 HT…

Moldflow模流分析教程

Moldflow模流分析教程&#xff1a;

计算机网络 3-4 数据链路层(局域网)

4.1 局域网LAN 特点 1.覆盖较小的地理范围 2.较低的时延和误码率 3.局域网内的各节点之间 4.支持单播、广播、多播 分类 关注三要素 &#xff08;出题点&#xff09; ①拓扑结构 ②传输介质 ③介质访问控制方式 硬件架构 4.2 以太网 4.2.1 层次划分 4.2.2 物理层标准…

单片机AIN0、AIN1引脚功能

目录 1. 模拟-数字转换器&#xff08;ADC&#xff09; 2. 交流电源&#xff08;AC&#xff09; 总结 这两部分有什么区别&#xff1f; 在这个电路图中&#xff0c;两个部分分别是模拟-数字转换器&#xff08;ADC&#xff09;和交流电源&#xff08;AC&#xff09;。以下是这…

如何增加 Elasticsearch 中的 primary shard 数量

作者&#xff1a;来自 Elastic Kofi Bartlett 探索增加 Elasticsearch 中 primary shard 数量的方法。 更多阅读&#xff1a; Elasticsearch&#xff1a;Split index API - 把一个大的索引分拆成更多分片 Elasticsearch&#xff1a;通过 shrink API 减少 shard 数量来缩小 El…

Java 并发性能优化:线程池的最佳实践

Java 并发性能优化&#xff1a;线程池的最佳实践 在 Java 并发编程的世界里&#xff0c;线程池堪称提高应用性能与稳定性的神器。恰如其分地运用线程池&#xff0c;能让我们在多线程任务调度时游刃有余&#xff0c;既能避免线程频繁创建销毁带来的开销&#xff0c;又能合理管控…

【综述】一文读懂卷积神经网络(CNN)

卷积神经网络&#xff08;Convolutional Neural Networks, CNN&#xff09;是一类包含卷积计算且具有深度结构的前馈神经网络&#xff08;Feedforward Neural Networks&#xff09;&#xff0c;是深度学习&#xff08;deep learning&#xff09;的代表算法之一。本文旨在介绍CN…

阿里云集群开启debug

1、安装 kubectl Macos brew install kubectl Windows&#xff1a; https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-windows/ 下载后&#xff0c;放到任意目录 2、配置连接信息 mac 将以下内容复制到计算机 $HOME/.kube/config 文件下: windows 不同集…

Unity之如何实现RenderStreaming视频推流

文章目录 前言引入 UnityRenderStreaming 的好处教程步骤 1:设置环境步骤 2: 创建项目步骤 3:安装软件包步骤 5:下载示例步骤 6:检查配置环境步骤 7:打开推流场景步骤 8: 准备用于流式传输的WebServer应用程序步骤 9: 运行 示例场景步骤 10:检查视频是否在浏览器中显示…

【java实现+4种变体完整例子】排序算法中【桶排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格

以下是桶排序的详细解析&#xff0c;包含基础实现、常见变体的完整代码示例&#xff0c;以及各变体的对比表格&#xff1a; 一、桶排序基础实现 原理 将数据分到有限数量的桶中&#xff0c;每个桶内部使用其他排序算法&#xff08;如插入排序或快速排序&#xff09;&#xf…

计算机三级:信息安全基础技术与原理(2.1密码技术简单梳理)

以下是密码学发展历程的表格归纳: ​发展阶段​时间范围​关键节点与标志性技术​技术突破与核心贡献​古典密码时期古代至19世纪• 公元前17世纪 克里特岛Phaistos圆盘(未知符号加密) • 中国西周“阴符”、北宋五言诗密码 • 1466年 艾伯蒂多表代替密码 • 1883年 克尔克霍…

【每天一个知识点】模式识别

“模式识别”是一种从数据中识别出规律、结构或趋势的技术&#xff0c;它广泛应用于人工智能、机器学习、图像处理、语音识别、自然语言处理等领域。简单来说&#xff0c;就是让计算机学会“看出”数据中的规律&#xff0c;比如&#xff1a; 从图像中识别人脸&#xff08;人脸识…

Codeforces Educational Round 177 Div. 2 【B题,C待补

B 二分 题意 样例 5 3 10 3 4 2 1 512 找最右边的L下标即可 思路 二分最靠右的L端点&#xff0c;R端点取最右端(n*k处)&#xff0c;找到后&#xff0c;答案就是L的位置(pos)&#xff0c;&#xff08;因为如果pos满足&#xff0c;则pos左边的所有下标都满足 代码 const in…

哈夫曼编码和哈夫曼树

哈夫曼编码&#xff08;Huffman Coding&#xff09; 是一种基于字符出现频率的无损数据压缩算法&#xff0c;通过构建哈夫曼树&#xff08;Huffman Tree&#xff09; 来生成最优前缀编码&#xff0c;使得高频字符用短编码&#xff0c;低频字符用长编码&#xff0c;从而实现高效…

中西面点实训室虚拟仿真操作平台

在餐饮行业蓬勃发展的当下&#xff0c;中西面点作为其中极具特色与市场需求的重要分支&#xff0c;对于专业人才的渴望愈发强烈。一个功能完备、设施先进的中西面点实训室&#xff0c;已然成为培养高素质面点专业人才的关键阵地。凯禾瑞华——实训室建设 一、中西面点实训室建设…