【Java可执行命令】(二十一)线程快照生成工具 jstack:帮助开发人员分析和排查线程相关问题(死锁、死循环、线程阻塞...)

Java可执行命令之jstack

  • 1️⃣ 概念
  • 2️⃣ 优势和缺点
  • 3️⃣ 使用
      • 3.1 语法格式
      • 3.2 使用步骤及技巧
      • 3.3 使用案例
  • 4️⃣ 应用场景
  • 🌾 总结

在这里插入图片描述


1️⃣ 概念

jstack 命令是 Java Development Kit(JDK)中提供的一项诊断工具,用于生成Java虚拟机(JVM)的线程快照。它的主要设计目的是帮助开发人员分析和排查应用程序中的线程相关问题,如死锁、死循环、线程阻塞等。

线程快照是指在某个时间点上,记录下所有运行在JVM中的线程的状态信息,包括线程栈、线程ID、线程所属的进程ID等。通过线程快照,我们可以了解线程执行状态、调用堆栈、线程的持有锁、等待资源等详细信息。

jstack 命令工具有以下特征:

  • 生成文本文件:jstack 命令生成的线程快照以文本文件形式输出,方便存储和后续分析;
  • 多种输出格式:jstack 提供了多种输出格式,如16进制、16进制元数据等,以满足不同场景下的需求;
  • 线程状态信息:线程快照中包含了每个线程的状态信息,如WAITINGTIMED_WAITINGBLOCKED等;
  • 堆栈追踪:通过解析线程的栈帧(Stack Frame),可以查看线程执行的方法调用轨迹。这对于发现死锁或代码性能调优至关重要。

jstack的原理实际是通过Java虚拟机提供的ThreadMXBean 接口获取线程相关信息,并将获取到的信息打印到控制台或文本文件中。它会遍历JVM中的所有线程,然后获取线程堆栈信息和其他状态信息,最终输出线程快照。

2️⃣ 优势和缺点

优点:

  • jstack命令能够提供关键的线程信息,方便开发人员快速定位和诊断线程相关问题;
  • JDK自带的工具,无需额外配置,使用方便;
  • 命令执行速度较快,在诊断简单问题方面效果良好。

缺点:

  • jstack只提供静态的线程快照,不能实时监控和连续跟踪线程,在某些复杂场景下可能不够全面。

3️⃣ 使用

3.1 语法格式

jstack 命令的使用语法如下:

Usage:jstack [-l] <pid>(to connect to running process)(连接到正在运行的进程)jstack -F [-m] [-l] <pid>(to connect to a hung process)(连接到挂起的进程)jstack [-m] [-l] <executable> <core>(to connect to a core file)(连接到核心文件)jstack [-m] [-l] [server_id@]<remote server IP or hostname>(to connect to a remote debug server)(连接到远程调试服务器)

其中,[-l] -F[-m] 都是可选的一些命令参数选项,<pid> 是Java进程的进程ID。对于命令中可选参数汇总如下:

参数说明
-F以强制线程转储。当 jstack<pid>没有响应时使用(进程挂起)
-m打印java和本机框架(混合模式)
-l长清单,打印有关锁的其他信息
-h or -help打印帮助信息

需要注意以下几点:

  • 在使用jstack命令生成线程快照时,目标Java进程可能会暂停执行,影响应用程序的性能;
  • 对于生产环境的Java进程,建议在非高峰期或业务低谷时使用 jstack命令,以减少对正常业务流程的干扰;
  • 考虑保密性:线程快照可能包含敏感信息(如部分代码逻辑),请确保妥善处理线程快照文件以防止泄露。

3.2 使用步骤及技巧

  • 找到目标进程的 PID:可以通过jps命令来查看Java进程的进程ID;
  • 执行命令:在命令行中输入jstack <pid>,即可生成线程快照;
  • 分析线程信息:打开生成的线程快照文本文件,查看线程状态、堆栈追踪等信息;
  • 利用线程ID定位问题:根据线程ID可以在堆栈追踪中定位对应的代码和资源问题,帮助进行问题诊断。

对于大规模线程的应用程序,可以使用多次执行jstack <pid>并比较不同快照的结果,以检测潜在的线程问题。
同时也可以结合其他工具(如jvisualvm)使用,可以更全面地分析和调试线程相关问题。

3.3 使用案例

(1)通过jps命令来查看Java进程的进程ID;

c:\Users\xxx\IdeaProjects\untitled15\src\com\xiaoshan>jps
15216 TestDemo
166976 Launcher
172008 Jps
172716

(2)在命令行中输入jstack ,生成线程快照;

c:\Users\xxx\IdeaProjects\untitled15\src\com\xiaoshan>jstack 15216

执行结果:

2023-08-09 15:19:52
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.202-b08 mixed mode):"Service Thread" #11 daemon prio=9 os_prio=0 tid=0x00000000193c8800 nid=0x2a5d4 runnable [0x0000000000000000]java.lang.Thread.State: RUNNABLE"C1 CompilerThread3" #10 daemon prio=9 os_prio=2 tid=0x00000000193a8000 nid=0x28a78 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLE"C2 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000001939e800 nid=0x2a108 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLE"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000001939e000 nid=0x29dd0 waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLE"C2 CompilerThread0" #7 daemon prio=9 os_prio=2 tid=0x0000000019399800 nid=0x25afc waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLE"Monitor Ctrl-Break" #6 daemon prio=5 os_prio=0 tid=0x00000000193a0000 nid=0x29528 runnable [0x000000001a9be000]java.lang.Thread.State: RUNNABLEat java.net.SocketInputStream.socketRead0(Native Method)at java.net.SocketInputStream.socketRead(SocketInputStream.java:116)at java.net.SocketInputStream.read(SocketInputStream.java:171)at java.net.SocketInputStream.read(SocketInputStream.java:141)at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)- locked <0x00000000d6688070> (a java.io.InputStreamReader)at java.io.InputStreamReader.read(InputStreamReader.java:184)at java.io.BufferedReader.fill(BufferedReader.java:161)at java.io.BufferedReader.readLine(BufferedReader.java:324)- locked <0x00000000d6688070> (a java.io.InputStreamReader)at java.io.BufferedReader.readLine(BufferedReader.java:389)at com.intellij.rt.execution.application.AppMainV2$1.run(AppMainV2.java:49)"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x0000000019353000 nid=0x28dbc waiting on condition [0x0000000000000000]java.lang.Thread.State: RUNNABLE"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x0000000019300000 nid=0x2a1b8 runnable [0x0000000000000000]java.lang.Thread.State: RUNNABLE"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x0000000017c23800 nid=0x2a5b8 in Object.wait() [0x000000001a64f000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x00000000d6508ed0> (a java.lang.ref.ReferenceQueue$Lock)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:144)- locked <0x00000000d6508ed0> (a java.lang.ref.ReferenceQueue$Lock)at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:165)at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:216)"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000000192e3000 nid=0x2a504 in Object.wait() [0x000000001a54f000]java.lang.Thread.State: WAITING (on object monitor)at java.lang.Object.wait(Native Method)- waiting on <0x00000000d6506bf8> (a java.lang.ref.Reference$Lock)at java.lang.Object.wait(Object.java:502)at java.lang.ref.Reference.tryHandlePending(Reference.java:191)- locked <0x00000000d6506bf8> (a java.lang.ref.Reference$Lock)at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)"main" #1 prio=5 os_prio=0 tid=0x0000000002a63000 nid=0x2a1bc runnable [0x00000000024be000]java.lang.Thread.State: RUNNABLEat java.io.FileInputStream.readBytes(Native Method)at java.io.FileInputStream.read(FileInputStream.java:255)at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)at java.io.BufferedInputStream.read(BufferedInputStream.java:265)- locked <0x00000000d655a9c0> (a java.io.BufferedInputStream)at com.xiaoshan.test.TestDemo.main(TestDemo.java:38)"VM Thread" os_prio=2 tid=0x0000000017c16800 nid=0x1414 runnable"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x0000000002a78800 nid=0x27c9c runnable"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x0000000002a7a000 nid=0x296a0 runnable"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x0000000002a7b800 nid=0x2a498 runnable"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x0000000002a7d000 nid=0x2a304 runnable"GC task thread#4 (ParallelGC)" os_prio=0 tid=0x0000000002a7f800 nid=0x470 runnable"GC task thread#5 (ParallelGC)" os_prio=0 tid=0x0000000002a81800 nid=0x2794c runnable"GC task thread#6 (ParallelGC)" os_prio=0 tid=0x0000000002a85000 nid=0x5450 runnable"GC task thread#7 (ParallelGC)" os_prio=0 tid=0x0000000002a86000 nid=0x47bc runnable"GC task thread#8 (ParallelGC)" os_prio=0 tid=0x0000000002a87000 nid=0x29ec0 runnable"GC task thread#9 (ParallelGC)" os_prio=0 tid=0x0000000002a88800 nid=0x2a624 runnable"VM Periodic Task Thread" os_prio=2 tid=0x00000000193c9000 nid=0x29c78 waiting on conditionJNI global references: 12

此结果是Java虚拟机线程转储(Full thread dump)的输出。它提供了一个关于在Java程序中正在运行的所有线程的信息快照。以下是每个线程的解释:

  1. "Service Thread":服务线程,是用于执行后台任务的线程。
  2. "C1 CompilerThread3":即时编译器线程,负责编译Java字节码为本地代码,以提高执行效率。
  3. "C2 CompilerThread2":另一个即时编译器线程,也负责编译Java字节码为本地代码。
  4. "C2 CompilerThread1":即时编译器线程的另一个实例。
  5. "C2 CompilerThread0":即时编译器线程的另一个实例。
  6. "Monitor Ctrl-Break":监控Ctrl-Break事件的线程,可用于在IDE中终止程序执行。
  7. "Attach Listener":监听Java虚拟机附加事件的线程。
  8. "Signal Dispatcher":信号分发线程,用于处理操作系统发送的信号。
  9. "Finalizer":Finalizer线程,负责执行对象的finalize()方法(垃圾回收前的清理工作)。
  10. "Reference Handler":引用处理线程,用于处理Reference类型的对象。
  11. "main":主线程,程序的入口点。
  12. "VM Thread":虚拟机线程,执行必要的虚拟机任务。
  13. "GC task thread#0 (ParallelGC)""GC task thread#9 (ParallelGC)":并行垃圾回收(ParallelGC)线程。在此例中,有10个线程用于并行垃圾回收。
  14. "VM Periodic Task Thread":周期性任务线程,定期执行虚拟机内部的一些任务。

最后一行指示JNI全局引用的数量为12,这是Java Native Interface(JNI)使用的内存资源。

以"Service Thread"线程为例,详细解释一个线程的输出信息:

"Service Thread" #11 daemon prio=9 os_prio=0 tid=0x00000000193c8800 nid=0x2a5d4 runnable [0x0000000000000000]java.lang.Thread.State: RUNNABLE
  • 线程名称:“Service Thread”;
  • 线程编号(Thread ID):0x00000000193c8800
  • Native ID(nid):0x2a5d4
  • 守护线程标识(daemon):守护线程(daemon),这意味着当所有非守护线程结束时,该线程会被自动终止;
  • 线程优先级(priority):9,具有10个等级的优先级范围(1为最低,10为最高);
  • 操作系统优先级(os_priority):0,表示该线程在操作系统中使用默认的优先级设置;
  • 线程特定标识符(tid):0x00000000193c8800
  • 线程状态(java.lang.Thread.State):RUNNABLE,表示该线程当前正在运行或准备运行。

总而言之,该输出提供了关于Java程序运行时各个线程的详细信息,包括线程名称、优先级、状态以及线程正在执行的代码位置(如果可获得)。

4️⃣ 应用场景

  • 线程死锁定位:通过观察线程快照中的锁信息,可以排查应用程序中的死锁问题;
  • 程序性能分析:通过分析线程状态和堆栈信息,可以发现耗时操作、线程阻塞等导致程序性能下降的原因;
  • 代码调优:通过观察方法调用轨迹,可以确定是否存在效率低下的代码段,进而进行优化。

🌾 总结

jstack 命令是Java开发人员调试和分析线程相关问题时常用的工具。它能够生成线程快照,提供有关线程状态和堆栈追踪的重要信息,帮助开发人员定位线程问题、代码性能问题以及资源争用问题。尽管其输出是静态的,不能实时监控线程状态,但是在处理简单线程问题时具有较高的效果。

了解jstack的使用方法、特征、优化技巧和注意事项,能够提升开发人员在排查线程问题方面的能力,进一步提升应用程序的性能和稳定性。

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

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

相关文章

WHQL认证中HCK和HLK的区别

开发者或硬件制造商要通过WHQL认证获得微软数字签名或是Windows徽标的使用权限&#xff0c;就需要使用WHQL认证的测试工具&#xff08;HCK或HLK&#xff09;对硬件设备或驱动程序进行测试。HCK和HLK其实是一个系列的测试工具&#xff0c;HCK和HLK的主要区别是用于测试不同Windo…

pytest测试框架之fixture测试夹具详解

fixture的优势 ​ pytest框架的fixture测试夹具就相当于unittest框架的setup、teardown&#xff0c;但相对之下它的功能更加强大和灵活。 命名方式灵活&#xff0c;不限于unittest的setup、teardown可以实现数据共享&#xff0c;多个模块跨文件共享前置后置可以实现多个模块跨…

JAVA SpringBoot 项目 多线程、线程池的使用。

1.1 线程&#xff1a; 线程就是进程中的单个顺序控制流&#xff0c;也可以理解成是一条执行路径 单线程&#xff1a;一个进程中包含一个顺序控制流&#xff08;一条执行路径&#xff09; 多线程&#xff1a;一个进程中包含多个顺序控制流&#xff08;多条执行路径&#xff0…

天津农商银行智能加密锁管理工具常见问题

天津农商银行智能加密锁管理工具&#xff0c;在使用过程中&#xff0c;可能出现一些莫名的错误&#xff0c;针对亲身遇到的坑&#xff0c;分享给大家&#xff0c;以备不时之需。 一、转账业务导入文件中文汉字出现乱码&#xff0c;如下图。 原因是文件编码不正确&#xff0c;…

Java项目作业~ 创建基于Maven的Java项目,连接数据库,实现对站点信息的管理,即实现对站点的新增,修改,删除,查询操作

需求&#xff1a; 创建基于Maven的Java项目&#xff0c;连接数据库&#xff0c;实现对站点信息的管理&#xff0c;即实现对站点的新增&#xff0c;修改&#xff0c;删除&#xff0c;查询操作。 以下是站点表的建表语句&#xff1a; CREATE TABLE websites (id int(11) NOT N…

收钱吧与火山引擎VeDI合作一年后 有了哪些新变化?

更多技术交流、求职机会&#xff0c;欢迎关注字节跳动数据平台微信公众号&#xff0c;回复【1】进入官方交流群 收钱吧正在和火山引擎数智平台&#xff08;VeDI&#xff09;跑出一条业务提效新通路。 相关数据显示&#xff0c;收钱吧的日服务人次就近5000万&#xff0c;累计服务…

测评HTTP代理的透明匿名?

在我们日常的网络冒险中&#xff0c;你是否曾听说过HTTP代理的透明匿名特性&#xff1f;这些神秘的工具就像是网络世界中的隐身斗士&#xff0c;让我们能够在互联网的迷雾中保护自己的身份和隐私。那么&#xff0c;让我们一起揭开HTTP代理的面纱&#xff0c;探索其中的奥秘吧&a…

el-table实现指定列合并

table传入span-method方法可以实现合并行或列&#xff0c;方法的参数是一个对象&#xff0c;里面包含当前行row、当前列column、当前行号rowIndex、当前列号columnIndex四个属性。该函数可以返回一个包含两个元素的数组&#xff0c;第一个元素代表rowspan&#xff0c;第二个元素…

Qt多线程编程

本章介绍Qt多线程编程。 1.方法 Qt多线程编程通常有2种方法&#xff1a; 1)通过继承QThread类&#xff0c;实现run()方法。 2)采用QObject::moveToThread()方法。 方法2是Qt官方推荐的方法&#xff0c;本文介绍第2种。 2.步骤 1)创建Worker类 这里的Worker类就是我们需要…

数学·包含学科简介

数学包含学科简介 14 逻辑与基础 ▪ 1410:演绎逻辑学 ▪ 1420:证明论 ▪ 1430:递归论 ▪ 1440:模型论 ▪ 1450:公理集合论 ▪ 1460:数学基础 ▪ 1499:数理逻辑与数学基础其他学科 17 数论 ▪ 1710:初等数论 ▪ 1720:解析数论 ▪ 1730:代数数论 ▪ 1740:超越数论 ▪ 1750:丢…

FPGA开发:音乐播放器

FPGA开发板上的蜂鸣器可以用来播放音乐&#xff0c;只需要控制蜂鸣器信号的方波频率、占空比和持续时间即可。 1、简谱原理 简谱上的4/4表示该简谱以4分音符为一拍&#xff0c;每小节4拍&#xff0c;简谱上应该也会标注每分钟多少拍。音符时值对照表如下图所示&#xff0c;这表…

大模型老是胡说八道怎么办?哈佛大学提出推理干预ITI技术有效缓解模型幻觉现象

论文链接&#xff1a;https://arxiv.org/abs/2306.03341 代码仓库&#xff1a;https://github.com/likenneth/honest_llama 近来与ChatGPT有关的大模型的话题仍然处于风口浪尖&#xff0c;但是大家讨论的方向已经逐渐向大语言模型的实际应用、安全、部署等方面靠近。虽然大模型…

Gartner发布《2023年全球RPA魔力象限》:90%RPA厂商,将提供生成式AI自动化

8月3日&#xff0c;全球著名咨询调查机构Gartner发布了《2023年全球RPA魔力象限》&#xff0c;通过产品能力、技术创新、市场影响力等维度&#xff0c;对全球16家卓越RPA厂商进行了深度评估。 弘玑Cyclone&#xff08;Cyclone Robotics&#xff09;、来也&#xff08;Laiye&am…

(九)人工智能应用--深度学习原理与实战--前馈神经网络实现MNST手写数字识别

目标: 识别手写体的数字,如图所示: 学习内容: 1、掌握MNIST数据集的加载和查看方法 2、熟练掌握Keras建立前馈神经网络的步骤【重点】 3、掌握模型的编译及拟合方法的使用,理解参数含义【重点】 4、掌握模型的评估方法 5、掌握模型的预测方法 6、掌握自定义图片的处理与预测 …

Modelsim恢复编辑器的解决方案——只能将外部编辑器删除后,重新匹配编辑器

Modelsim恢复编辑器的解决方案——只能将外部编辑器删除后&#xff0c;重新匹配编辑器 1&#xff0c;Modelsim和Questasim是相互兼容的&#xff0c;配置的编辑器变成了sublime&#xff0c;且更换不了编辑器2&#xff0c;解决问题的方案&#xff0c;还是没得到解决3&#xff0c;…

Rpc原理

dubbo原理 1、RPC原理 一次完整的RPC调用流程&#xff08;同步调用&#xff0c;异步另说&#xff09;如下&#xff1a; 1&#xff09;服务消费方&#xff08;client&#xff09;调用以本地调用方式调用服务&#xff1b; 2&#xff09;client stub接收到调用后负责将方法、参数…

堡塔面板系统加固使用说明

更新日志&#xff1a; 宝塔系统加固5.0- 正式版 2023-08-07 1.加固php 配置文件 2.加固nginx 启动文件 宝塔系统加固4.1- 正式版 1、【修复】系统加固不会随系统启动自动开启的问题 2、【优化】大幅降低CPU使用率 宝塔系统加固4.0- 正式版 1、【增加】等保加固相关加固功能 2、…

高中教师能去美国做访问学者吗?

美国作为世界上高等教育水平较高的国家之一&#xff0c;吸引了众多学者前往交流学习。那么高中教师是否能够成为美国访问学者&#xff0c;这是当然的&#xff0c;高中老师是可以出国访学的&#xff0c;但是出国做访问学者会涉及到多方面的因素。 首先&#xff0c;教师个人的学术…

【torch.nn.Fold】和【torch.nn.Unfold】

文章目录 torch.nn.Unfold直观理解官方文档 toch.nn.Fold直观理解官方文档 torch.nn.Unfold 直观理解 torhc.nn.Unfold的功能&#xff1a; 从一个batch的样本中&#xff0c;提取出滑动的局部区域块patch&#xff08;也就是卷积操作中的提取kernel filter对应的滑动窗口&#…

Qt做警告处理界面

解决的问题&#xff1a; 做上位机时&#xff0c;多有检测仪器状态&#xff0c;事实显示警告&#xff0c;错误等状态&#xff0c;笔者就是需要显示各种仪器状态&#xff0c;做显示&#xff0c;后做出处理逻辑 Axure设计图&#xff1a; 需求&#xff1a;更新状态&#xff0c;根…