文章目录

  • 简介
  • jstack的命令格式
  • jstack的使用
  • 总结

简介

在之前的文章中,我们介绍了JDK14中jstat工具的使用,本文我们再深入探讨一下jstack工具的使用。

jstack工具主要用来打印java堆栈信息,主要是java的class名字,方法名,字节码索引,行数等信息。

更多精彩内容且看:

  • 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新
  • Spring Boot 2.X系列教程:七天从无到有掌握Spring Boot-持续更新
  • Spring 5.X系列教程:满足你对Spring5的一切想象-持续更新
  • java程序员从小工到专家成神之路(2020版)-持续更新中,附详细文章教程

更多内容请访问www.flydean.com

jstack的命令格式

Usage:jstack [-l][-e] <pid>(to connect to running process)Options:-l  long listing. Prints additional information about locks-e  extended listing. Prints additional information about threads-? -h --help -help to print this help message

jstack的参数比较简单,l可以包含锁的信息,e包含了额外的信息。

jstack的使用

我们举个例子:

jstack -l -e 53528

输出结果如下:

2020-05-09 21:46:51
Full thread dump Java HotSpot(TM) 64-Bit Server VM (14.0.1+7 mixed mode, sharing):Threads class SMR info:
_java_thread_list=0x00007fda0660eb00, length=14, elements={0x00007fda04811000, 0x00007fda05845800, 0x00007fda05012000, 0x00007fda05847800,
0x00007fda05843800, 0x00007fda05854800, 0x00007fda0481f000, 0x00007fda0481f800,
0x00007fda04018800, 0x00007fda041ff800, 0x00007fda05a28800, 0x00007fda05b1a800,
0x00007fda05b1d800, 0x00007fda042be000
}"Reference Handler" #2 daemon prio=10 os_prio=31 cpu=0.67ms elapsed=66335.21s allocated=0B defined_classes=0 tid=0x00007fda04811000 nid=0x4603 waiting on condition  [0x000070000afe1000]java.lang.Thread.State: RUNNABLEat java.lang.ref.Reference.waitForReferencePendingList(java.base@14.0.1/Native Method)at java.lang.ref.Reference.processPendingReferences(java.base@14.0.1/Reference.java:241)at java.lang.ref.Reference$ReferenceHandler.run(java.base@14.0.1/Reference.java:213)Locked ownable synchronizers:- None..."VM Thread" os_prio=31 cpu=1433.78ms elapsed=66335.22s tid=0x00007fda0506b000 nid=0x4803 runnable"GC Thread#0" os_prio=31 cpu=18.63ms elapsed=66335.23s tid=0x00007fda0502a800 nid=0x3203 runnable"GC Thread#1" os_prio=31 cpu=19.64ms elapsed=66334.06s tid=0x00007fda050e5800 nid=0x9d03 runnable"GC Thread#2" os_prio=31 cpu=17.72ms elapsed=66334.06s tid=0x00007fda05015000 nid=0x6203 runnable"GC Thread#3" os_prio=31 cpu=14.57ms elapsed=66332.78s tid=0x00007fda05138800 nid=0x6503 runnable"G1 Main Marker" os_prio=31 cpu=0.25ms elapsed=66335.23s tid=0x00007fda05031000 nid=0x3303 runnable"G1 Conc#0" os_prio=31 cpu=14.85ms elapsed=66335.23s tid=0x00007fda05031800 nid=0x4b03 runnable"G1 Refine#0" os_prio=31 cpu=3.25ms elapsed=66335.23s tid=0x00007fda0583a800 nid=0x4a03 runnable"G1 Young RemSet Sampling" os_prio=31 cpu=5929.79ms elapsed=66335.23s tid=0x00007fda0505a800 nid=0x3503 runnable
"VM Periodic Task Thread" os_prio=31 cpu=21862.12ms elapsed=66335.13s tid=0x00007fda0505b000 nid=0xa103 waiting on conditionJNI global refs: 43, weak refs: 45

输出的结果我们可以分为下面几个部分:

JVM虚拟机信息

第一部分是JVM虚拟机的信息

2020-05-09 21:46:51
Full thread dump Java HotSpot(TM) 64-Bit Server VM (14.0.1+7 mixed mode, sharing):

上面显示了虚拟机的thread dump时间和虚拟机的版本等信息。

Threads class SMR info

第二部分是JVM中非JVM(非VM和非GC的线程)的内部线程信息。

Threads class SMR info:
_java_thread_list=0x00007fda0660eb00, length=14, elements={0x00007fda04811000, 0x00007fda05845800, 0x00007fda05012000, 0x00007fda05847800,
0x00007fda05843800, 0x00007fda05854800, 0x00007fda0481f000, 0x00007fda0481f800,
0x00007fda04018800, 0x00007fda041ff800, 0x00007fda05a28800, 0x00007fda05b1a800,
0x00007fda05b1d800, 0x00007fda042be000
}

这些elements是和后面线程的tid相匹配的。表示的是本地线程对象的地址,注意这些不是线程的ID。

大家可能注意到了里面写的是SMR, SMR全称是Safe Memory Reclamation。

什么是SMR呢?简单点讲就是安全的内存分配,一般这个问题会出现在非自动GC的编程语言中如C++。在这些语言中,需要自己来为对象分配内存和销毁对象,这样就可能导致在多线程的环境中,一个地址可能被分配给了多个对象,从而出现了内存分配的不安全。

线程信息

第三部分就是线程的具体信息了:

"Reference Handler" #2 daemon prio=10 os_prio=31 cpu=0.67ms elapsed=66335.21s allocated=0B defined_classes=0 tid=0x00007fda04811000 nid=0x4603 waiting on condition  [0x000070000afe1000]java.lang.Thread.State: RUNNABLEat java.lang.ref.Reference.waitForReferencePendingList(java.base@14.0.1/Native Method)at java.lang.ref.Reference.processPendingReferences(java.base@14.0.1/Reference.java:241)at java.lang.ref.Reference$ReferenceHandler.run(java.base@14.0.1/Reference.java:213)Locked ownable synchronizers:- None

按照字段的顺序,我们可以把线程信息分为下面几个部分:

  • 线程名字:例如Reference Handler
  • 线程的ID:例如#2
  • 是否守护线程:例如daemon,daemon threads是低优先级的thread,它的作用是为User Thread提供服务。 因为daemon threads的低优先级,并且仅为user thread提供服务,所以当所有的user thread都结束之后,JVM会自动退出,不管是否还有daemon threads在运行中。
  • 优先级:例如prio=10
  • OS线程的优先级:例如os_prio=31
  • cpu时间:线程获得CPU的时间,例如cpu=0.67ms
  • elapsed:线程启动后经过的wall clock time
  • allocated:本线程分配的分配的bytes数
  • defined_classes:本线程定义的class个数

注意’allocated=’ 和 ‘defined_classes=’ 必须要开启 -XX:+PrintExtendedThreadInfo才会输出数据。

  • Address:java线程的地址,例如:tid=0x00007fda04811000
  • OS线程ID:例如nid=0x4603
  • 线程状态:例如waiting on condition
  • 最新的Java堆栈指针:最新的java堆栈指针SP,例如:[0x000070000afe1000]

Thread Stack Trace

接下来就是线程的堆栈信息:

java.lang.Thread.State: RUNNABLEat java.lang.ref.Reference.waitForReferencePendingList(java.base@14.0.1/Native Method)at java.lang.ref.Reference.processPendingReferences(java.base@14.0.1/Reference.java:241)at java.lang.ref.Reference$ReferenceHandler.run(java.base@14.0.1/Reference.java:213)

上面的例子是线程的堆栈信息,并且列出来了线程的状态。

Locked Ownable Synchronizer

接下来的部分是该线程拥有的,可用的用于同步的排它锁对象。

Ownable Synchronizer是一个同步器,这个同步器的同步属性是通过使用AbstractOwnableSynchronizer或者它的子类来实现的。

例如ReentrantLock和ReentrantReadWriteLock中的write-lock(注意不是read-lock,因为需要排它性)就是两个例子。

JVM Threads

接下来是JVM的线程信息,因为这个线程是JVM内部的,所以没有线程ID:

"VM Thread" os_prio=31 cpu=1433.78ms elapsed=66335.22s tid=0x00007fda0506b000 nid=0x4803 runnable"GC Thread#0" os_prio=31 cpu=18.63ms elapsed=66335.23s tid=0x00007fda0502a800 nid=0x3203 runnable"GC Thread#1" os_prio=31 cpu=19.64ms elapsed=66334.06s tid=0x00007fda050e5800 nid=0x9d03 runnable"GC Thread#2" os_prio=31 cpu=17.72ms elapsed=66334.06s tid=0x00007fda05015000 nid=0x6203 runnable"GC Thread#3" os_prio=31 cpu=14.57ms elapsed=66332.78s tid=0x00007fda05138800 nid=0x6503 runnable"G1 Main Marker" os_prio=31 cpu=0.25ms elapsed=66335.23s tid=0x00007fda05031000 nid=0x3303 runnable"G1 Conc#0" os_prio=31 cpu=14.85ms elapsed=66335.23s tid=0x00007fda05031800 nid=0x4b03 runnable"G1 Refine#0" os_prio=31 cpu=3.25ms elapsed=66335.23s tid=0x00007fda0583a800 nid=0x4a03 runnable"G1 Young RemSet Sampling" os_prio=31 cpu=5929.79ms elapsed=66335.23s tid=0x00007fda0505a800 nid=0x3503 runnable
"VM Periodic Task Thread" os_prio=31 cpu=21862.12ms elapsed=66335.13s tid=0x00007fda0505b000 nid=0xa103 waiting on condition

JNI References

最后一部分是JNI(Java Native Interface)引用的信息,注意这些引用可能会导致内存泄露,因为这些native的引用并不会被自动垃圾回收。

JNI global refs: 43, weak refs: 45

总结

jstack是分析线程的非常强大的工具,希望大家能够使用起来。

本文作者:flydean程序那些事

本文链接:http://www.flydean.com/jdk14-jvm-jstack/

本文来源:flydean的博客

欢迎关注我的公众号:程序那些事,更多精彩等着您!

JDK14性能管理工具:jstack使用介绍相关推荐

  1. JDK14性能管理工具:jstat使用介绍

    文章目录 简介 JStat命令 JStat Output Options class compiler gc gccapacity gcnew gcnewcapacity gcold gcoldcap ...

  2. JDK14性能管理工具:Jconsole详解

    文章目录 简介 JConsole 概览 内存 线程 类 VM信息 MBean 总结 简介 我们在开发java项目的时候,或多或少都会去用到Java的性能管理工具.有时候是为了提升应用程序的性能,有时候 ...

  3. JDK14性能管理工具:jmap和jhat使用介绍

    文章目录 简介 jmap clstats finalizerinfo histo dump jhat 总结 简介 我们在写代码的过程中,经常会遇到内存泄露的问题,比如某个集合中的对象没有被回收,或者内 ...

  4. 应用性能管理工具PinPoint介绍

    概述 下面给大家介绍一个开源的 APM (Application Performance Management/应用性能管理)工具 - Pinpoint.一个分布式事务跟踪系统的平台,思路基于goog ...

  5. Xamarin Anroid开发教程之Anroid开发工具及应用介绍

    Xamarin Anroid开发教程之Anroid开发工具及应用介绍 Xamarin开发Anroid应用介绍 如今智能手机已经盛行了好几年,而针对这些智能手机的软件开发也变得异常火热.但是在Andro ...

  6. 13.5.虚拟化工具--jhat详解、13.6.虚拟化工具--jstack详解

    13.5.虚拟化工具–jhat详解 一般不通过这个命令执行,而是通过图形化工具类查看jvm信息. 在页面下有: 查看什么是OQL语句 在页面上有OQL help,可以查看OQL的语法. 13.6.虚拟 ...

  7. 开源性能测试工具 - Apache ab 介绍

    开源性能测试工具 - Apache ab 介绍 简介 ab的全称是ApacheBench,是 Apache 附带的一个小工具,专门用于 HTTP Server 的benchmark testing,可 ...

  8. GoLang语言多版本管理工具--GVM入门介绍

    GoLang语言多版本管理工具--GVM入门介绍 GVM 由Josh Bussdieker(jbuss,jaja,jbussdieker)在Moovweb工作期间 GVM提供了一个管理Go版本的界面. ...

  9. linux java 工具_Linux运维知识之linux下java版本管理工具jenv使用介绍

    本文主要向大家介绍了Linux运维知识之linux下java版本管理工具jenv使用介绍,通过具体的内容向大家展现,希望对大家学习Linux运维知识有所帮助. 不同的项目使用的java版本不同,每次切 ...

最新文章

  1. (转载兼整理)Linux 2.6 下通过 ptrace 和 plt 实现用户态 API Hook
  2. 【多线程】线程池拒绝策略详解与自定义拒绝策略
  3. CrystalDecisions.CrystalReports.Engine.LoadSaveReportException:載入報表失敗6/25
  4. cvc 降噪_耳机降噪功能这么多,说说什么是ANC、ENC、CVC、DSP降噪
  5. WP7 网络请求之WebClient
  6. python的前端开发_Python开发【前端】:html
  7. java sessionid长度_设置TOMCAT SESSIONID 字符长度和生成算法
  8. 通过Xshell来访问和连接Linux
  9. No repository found containing,eclipse 自动更新erro 解决
  10. 使用QRCode生成二维码
  11. scala的三个排序方法
  12. excel辅助列巧妙运用完成工资条的制作
  13. 个股打板机会:国民技术(实战)
  14. sql语句中表格缩写命名_数据库表字段命名规范
  15. python 重命名文件出现乱码_python处理文件名乱码
  16. [AngularJS面面观] 15. 依赖注入 --- 初识注入器(Injector)
  17. U3D记腾讯面试经历
  18. andriod studio 运行项目时没有NDK(Android Studio如何更改JDK和SDK或者DNK的路径)
  19. 光量子计算机的信息载体,如何使“孤傲”的光子改变彼此的量子态?
  20. weblogic 启动问题

热门文章

  1. OpenCV源码安装教程(兼容CUDA)
  2. Docker教程-仓库管理
  3. pcb地线应该不应该做成环路_干货|图文详解EMC的PCB设计技术
  4. C语言实现缓冲区溢出实例
  5. 完成端口(Completion Port)详解----- By PiggyXP(小猪)
  6. 交换机网络嗅探方法之用ARP欺骗辅助嗅探
  7. selenium的使用教程2
  8. 解决Git中的fatal: refusing to merge unrelated histories
  9. 从体验出发构建以增长为目标的视频服务体系
  10. 技术实战 —— 快速实现语聊房搭建