深入解析 JDK jstack 命令:线程分析的利器
你点赞了吗?你关注了吗?每天分享干货好文。
高并发解决方案与架构设计。
海量数据存储和性能优化。
通用框架/组件设计与封装。
如何设计合适的技术架构?
如何成功转型架构设计与技术管理?
在竞争激烈的大环境下,只有不断提升核心竞争力才能立于不败之地。
留言【我要晋级】,一对一指导,带你晋级。
引言
在 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"。 - 线程 ID:
tid=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: RUNNABLEat com.example.MyService.cpuIntensiveMethod(MyService.java:100)
6、分析代码逻辑,优化高 CPU 消耗的操作。
7、如果分析代码无法找到高 CPU 的理由时,就需要在一次请求中进行多次 thread dump 文件的转储,做先后对比,如果 runnable 的线程前后差异大,说明系统属于正常情况,是服务器资源不够的问题,需要加大服务器资源。如果是在执行同一个方法,那就说明该方法是有较大可能存在问题,还需要再去分析代码是否有优化的空间。
案例 3:线程长时间阻塞
步骤:
- 查找处于
BLOCKED或WAITING状态的线程。 - 分析锁的持有者和等待链:
"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. 自动化分析工具
- VisualVM:图形化工具,支持实时线程监控和转储分析。
- FastThread:在线线程转储分析工具(https://fastthread.io/)。
- IBM Thread and Monitor Dump Analyzer:用于复杂线程问题的分析。
2. 结合其他命令
- jps:快速查找 Java 进程 ID。
- jstat:监控 JVM 统计信息(GC、类加载等)。
- jmap:生成堆转储(Heap Dump)。
七、注意事项
- 权限问题:确保执行
jstack的用户有权限访问目标 Java 进程。 - 生产环境谨慎使用
-F:强制生成转储可能导致 JVM 暂停。 - 多次采样:对于偶现问题,建议多次生成线程转储进行对比分析。
八、总结
jstack 是 Java 开发者必须掌握的诊断工具,能够快速定位线程相关的问题。通过本文的学习,你已经掌握了以下技能:
- 生成和分析线程转储。
- 诊断死锁、CPU 占用过高、线程阻塞等常见问题。
- 使用高级工具优化分析效率。
架构设计之道在于在不同的场景采用合适的架构设计,架构设计没有完美,只有合适。
在代码的路上,我们一起砥砺前行。用代码改变世界!
如果有其它问题,欢迎评论区沟通。
感谢观看,如果觉得对您有用,还请动动您那发财的手指头,点赞、转发、在看、收藏。
高并发解决方案与架构设计。
海量数据存储和性能优化。
通用框架/组件设计与封装。
如何设计合适的技术架构?
如何成功转型架构设计与技术管理?
在竞争激烈的大环境下,只有不断提升核心竞争力才能立于不败之地。
留言【我要晋级】,一对一指导,带你晋级。
相关文章:
深入解析 JDK jstack 命令:线程分析的利器
你点赞了吗?你关注了吗?每天分享干货好文。 高并发解决方案与架构设计。 海量数据存储和性能优化。 通用框架/组件设计与封装。 如何设计合适的技术架构? 如何成功转型架构设计与技术管理? 在竞争激烈的大环境下,…...
【操作系统原理03】处理机调度与死锁
文章目录 大纲一.处理机调度概念与层次0.大纲1.基本概念2.三个层次3.七状态模型4.三层调度都对比与联系 二.进程调度的时机,切换与过程的调度方式0.大纲1.进程调度时机2.调度方式3.进程的切换与过程 三.调度器和闲逛资源1.调度器/调度程序2.闲逛进程 四.调度算法的评…...
Quipus,LightRag的Go版本的实现
1 项目简介 奇谱系统当前版本以知识库为核心,基于知识库可以快构建自己的问答系统。知识库的Rag模块的构建算法是参考了LightRag的算法流程的Go版本优化实现,它可以帮助你快速、准确地构建自己的知识库,搭建属于自己的AI智能助手。与当前LLM…...
使用 Vite 快速搭建现代化 React 开发环境
1.检查环境 说明:检测环境,node版本为18.20.6。 2.创建命令 说明:创建命令,选择对应的选项。 npm create vitelatest 3.安装依赖 说明:安装相关依赖。 npm i...
关于UE5的抗锯齿和TAA
关于闪烁和不稳定现象的详细解释 当您关闭抗锯齿技术时,场景中会出现严重的闪烁和不稳定现象,尤其在有细节纹理和小物体的场景中。这种现象的技术原因如下: 像素采样问题 在3D渲染中,每个像素只能表示一个颜色值,但…...
PG数据库推进医疗AI向量搜索优化路径研究(2025年3月修订版)
PG数据库推进医疗AI向量搜索优化路径研究 一、医疗 AI 向量搜索的发展现状与挑战 1.1 医疗数据特征与检索需求 医疗数据作为推动医疗领域进步与创新的关键要素,具有鲜明且复杂的特征。从多模态角度看,医疗数据涵盖了结构化数据,如患者基本信息、检验检查报告中的数值结果;…...
可穿戴经颅多通道直流电刺激产品测试总结
一 概念原理 tDCS 是一种非侵入性的神经调节技术,利用恒定、低强度直流电(通常为 0 - 2mA)通过电极作用于特定的大脑区域。其工作原理是通过调节神经元的膜电位,来增加或降低神经元兴奋性的特定区域,从而改变大脑运作。…...
什么是 Stream
Stream 是对集合对象功能的增强,它不是集合,也不存储数据,而是从集合中抽象出一条数据通道,让你可以用链式方式一步步处理数据。 🔧 常见操作分类 类型方法举例创建stream(), Stream.of(), Arrays.stream()中间操作fi…...
详解与HTTP服务器相关操作
HTTP 服务器是一种遵循超文本传输协议(HTTP)的服务器,用于在网络上传输和处理网页及其他相关资源。以下是关于它的详细介绍: 工作原理 HTTP 服务器监听指定端口(通常是 80 端口用于 HTTP,443 端口用于 HT…...
-XX:+HeapDumpOnOutOfMemoryError 会打印哪些oom错误
-XX:HeapDumpOnOutOfMemoryError 参数会在 JVM 发生以下 OutOfMemoryError(OOM) 错误时自动生成堆转储文件(Heap Dump),便于后续分析内存溢出原因: 一、触发转储的 OOM 错误类型 Java 堆溢出…...
Moldflow模流分析教程
Moldflow模流分析教程:...
计算机网络 3-4 数据链路层(局域网)
4.1 局域网LAN 特点 1.覆盖较小的地理范围 2.较低的时延和误码率 3.局域网内的各节点之间 4.支持单播、广播、多播 分类 关注三要素 (出题点) ①拓扑结构 ②传输介质 ③介质访问控制方式 硬件架构 4.2 以太网 4.2.1 层次划分 4.2.2 物理层标准…...
加密与解密完全指南,使用Java实现
文章目录 1. 加密基础知识1.1 什么是加密?1.2 加密的历史简介1.2.1 古典加密1.2.2 现代加密的起源1.3 加密的基本概念1.3.1 密码学中的关键术语1.3.2 加密的基本原则1.4 加密的分类1.4.1 对称加密(Symmetric Encryption)1.4.2 非对称加密(Asymmetric Encryption)1.4.3 哈希…...
单片机AIN0、AIN1引脚功能
目录 1. 模拟-数字转换器(ADC) 2. 交流电源(AC) 总结 这两部分有什么区别? 在这个电路图中,两个部分分别是模拟-数字转换器(ADC)和交流电源(AC)。以下是这…...
如何增加 Elasticsearch 中的 primary shard 数量
作者:来自 Elastic Kofi Bartlett 探索增加 Elasticsearch 中 primary shard 数量的方法。 更多阅读: Elasticsearch:Split index API - 把一个大的索引分拆成更多分片 Elasticsearch:通过 shrink API 减少 shard 数量来缩小 El…...
Java 并发性能优化:线程池的最佳实践
Java 并发性能优化:线程池的最佳实践 在 Java 并发编程的世界里,线程池堪称提高应用性能与稳定性的神器。恰如其分地运用线程池,能让我们在多线程任务调度时游刃有余,既能避免线程频繁创建销毁带来的开销,又能合理管控…...
【综述】一文读懂卷积神经网络(CNN)
卷积神经网络(Convolutional Neural Networks, CNN)是一类包含卷积计算且具有深度结构的前馈神经网络(Feedforward Neural Networks),是深度学习(deep learning)的代表算法之一。本文旨在介绍CN…...
Python爬虫实战:获取网易新闻数据
一、引言 随着互联网的飞速发展,网络上蕴含着海量的信息资源。新闻数据作为其中的重要组成部分,对于舆情分析、市场研究、信息传播等多个领域具有重要价值。网易新闻作为国内知名的新闻平台,拥有丰富多样的新闻内容。使用 Python 的 Scrapy 框架进行网易新闻数据的爬取,可…...
YOLO学习笔记 | 基于COCO Stuff数据集与YOLOv11的多类别物体检测与分割
基于COCO Stuff数据集与YOLOv11的多类别物体检测与分割技术解析 一、技术背景与YOLOv11核心改进 YOLOv11是Ultralytics推出的新一代目标检测与分割模型,在YOLOv8的基础上进一步优化了架构设计与训练流程。其核心改进包括: 自适应特征增强(AFE)模块:通过空间上下文模块(…...
ICS丨Chapter 1 Introduction to Computer System
Chapter 1 Introduction to Computer System Courses About Systems: DBMSDistributed SystemsCompilersArchitectureOperating Systemse.t.c. 1. Brief Introduction 1.1. What’s about CSAPP?1.2. Power of Abstraction1.3. Importance of understanding HOW things wor…...
阿里云集群开启debug
1、安装 kubectl Macos brew install kubectl Windows: https://kubernetes.io/zh-cn/docs/tasks/tools/install-kubectl-windows/ 下载后,放到任意目录 2、配置连接信息 mac 将以下内容复制到计算机 $HOME/.kube/config 文件下: windows 不同集…...
Flink Hive Catalog最佳实践
Flink Hive Catalog 最佳实践 一、配置与初始化 依赖管理 Hive Connector 版本对齐:需确保 flink-sql-connector-hive 版本与 Hive 版本严格匹配(如 Hive 3.1.3 对应 flink-sql-connector-hive-3.1.3_2.12),同时添加 Hadoop 遮蔽…...
Unity之如何实现RenderStreaming视频推流
文章目录 前言引入 UnityRenderStreaming 的好处教程步骤 1:设置环境步骤 2: 创建项目步骤 3:安装软件包步骤 5:下载示例步骤 6:检查配置环境步骤 7:打开推流场景步骤 8: 准备用于流式传输的WebServer应用程序步骤 9: 运行 示例场景步骤 10:检查视频是否在浏览器中显示…...
【java实现+4种变体完整例子】排序算法中【桶排序】的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格
以下是桶排序的详细解析,包含基础实现、常见变体的完整代码示例,以及各变体的对比表格: 一、桶排序基础实现 原理 将数据分到有限数量的桶中,每个桶内部使用其他排序算法(如插入排序或快速排序)…...
计算机三级:信息安全基础技术与原理(2.1密码技术简单梳理)
以下是密码学发展历程的表格归纳: 发展阶段时间范围关键节点与标志性技术技术突破与核心贡献古典密码时期古代至19世纪• 公元前17世纪 克里特岛Phaistos圆盘(未知符号加密) • 中国西周“阴符”、北宋五言诗密码 • 1466年 艾伯蒂多表代替密码 • 1883年 克尔克霍…...
基于CNN与VGG16的图像识别快速实现指南
基于CNN与VGG16的图像识别快速实现指南 以下是从零实现代码到原理剖析的完整流程,包含TensorFlow/Keras框架的代码示例与关键优化技巧,满足快速实验需求。 一、核心原理对比 特性CNN(基础模型)VGG16结构深度5-10层(如…...
【内置函数】84个Python内置函数全整理
Python 内置函数全集(完整分类 参数详解 示例) 文章目录 Python 内置函数全集(完整分类 参数详解 示例)一、数值与数学函数abs(x)divmod(a, b)pow(x, y, modNone)round(number[, ndigits])sum(iterable, /, start0)hash(obj) …...
【每天一个知识点】模式识别
“模式识别”是一种从数据中识别出规律、结构或趋势的技术,它广泛应用于人工智能、机器学习、图像处理、语音识别、自然语言处理等领域。简单来说,就是让计算机学会“看出”数据中的规律,比如: 从图像中识别人脸(人脸识…...
Codeforces Educational Round 177 Div. 2 【B题,C待补
B 二分 题意 样例 5 3 10 3 4 2 1 512 找最右边的L下标即可 思路 二分最靠右的L端点,R端点取最右端(n*k处),找到后,答案就是L的位置(pos),(因为如果pos满足,则pos左边的所有下标都满足 代码 const in…...
哈夫曼编码和哈夫曼树
哈夫曼编码(Huffman Coding) 是一种基于字符出现频率的无损数据压缩算法,通过构建哈夫曼树(Huffman Tree) 来生成最优前缀编码,使得高频字符用短编码,低频字符用长编码,从而实现高效…...

