这几天肝java并发编程,涉及到死锁时,要想查看是什么原因导致的线程死锁,就需要导出线程dump进行分析。jvm就有现成的工具来实现线程dump导出,具体步骤如下:
#### 1.查看java进程
首先,需要通过jps命令查看当前机器上的所有java进程,找出进程的pid。jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有java进程pid的命令,命令格式:jps [options] [hostid]
- [options]选项 :
- -q:仅输出VM标识符,不包括classname,jar name,arguments in main method
- -m:输出main method的参数
- -l:输出完全的包名,应用主类名,jar的完全路径名
- -v:输出jvm参数
- -V:输出通过flag文件传递到JVM中的参数(.hotspotrc文件或-XX:Flags=所指定的文件
- -Joption:传递参数到vm,例如:-J-Xms512m
- [hostid]选项 :指定特定主机,可以是ip地址和域名, 也可以指定具体协议,端口。
查看java进程全路径详情的命令如下:
```
[root@miantiao ~]# jps -l
```
查询结果为:
```
1088
4112 threadDemo.DeadLockDemo
16876 jdk.jcmd/sun.tools.jps.Jps
````
第一组数字就是java线程的pid,后面就是线程的全包名。
#### 2.导出线程信息
jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 Java 应用程序中线程堆栈信息。命令格式为:jstack [options] pid。
- [options]选项 :
- -l 长列表. 打印关于锁的附加信息,例如属于java.util.concurrent 的 ownable synchronizers列表。
- -F 当’jstack [-l] pid’没有相应的时候强制打印栈信息。
- -m 打印java和native c/c++框架的所有栈信息。
- -h | -help 打印帮助信息。
使用jstack命令将指定pid(例如4112)的线程的所有线程信息导出到指定文件中。命令如下:
```
[root@miantiao ~]# jstack -l 4112 > jvm_4112.log
```
最终,得到的线程信息为:
```
2020-03-23 19:58:59
Full thread dump Java HotSpot(TM) 64-Bit Server VM (11.0.3+12-LTS mixed mode):
Threads class SMR info:
_java_thread_list=0x0000020a6aa9bb20, length=12, elements={
0x0000020a6a01e800, 0x0000020a6a020000, 0x0000020a6a941800, 0x0000020a6a045000,
0x0000020a6a047000, 0x0000020a6a04d800, 0x0000020a6a955000, 0x0000020a6aae3000,
0x0000020a6aad2800, 0x0000020a6aad5800, 0x0000020a6aad6000, 0x0000020a470c5000
}
"Reference Handler" #2 daemon prio=10 os_prio=2 cpu=0.00ms elapsed=134.63s tid=0x0000020a6a01e800 nid=0x3c40 waiting on condition [0x000000ff4fbff000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList(java.base@11.0.3/Native Method)
at java.lang.ref.Reference.processPendingReferences(java.base@11.0.3/Reference.java:241)
at java.lang.ref.Reference$ReferenceHandler.run(java.base@11.0.3/Reference.java:213)
Locked ownable synchronizers:
- None
"Finalizer" #3 daemon prio=8 os_prio=1 cpu=0.00ms elapsed=134.63s tid=0x0000020a6a020000 nid=0x402c in Object.wait() [0x000000ff4fcff000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(java.base@11.0.3/Native Method)
- waiting on <0x0000000711d08f10> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@11.0.3/ReferenceQueue.java:155)
- waiting to re-lock in wait() <0x0000000711d08f10> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@11.0.3/ReferenceQueue.java:176)
at java.lang.ref.Finalizer$FinalizerThread.run(java.base@11.0.3/Finalizer.java:170)
Locked ownable synchronizers:
- None
"Signal Dispatcher" #4 daemon prio=9 os_prio=2 cpu=0.00ms elapsed=134.61s tid=0x0000020a6a941800 nid=0x3ab8 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Attach Listener" #5 daemon prio=5 os_prio=2 cpu=0.00ms elapsed=134.61s tid=0x0000020a6a045000 nid=0x3a94 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 cpu=0.00ms elapsed=134.61s tid=0x0000020a6a047000 nid=0x36c8 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task
Locked ownable synchronizers:
- None
"C1 CompilerThread0" #8 daemon prio=9 os_prio=2 cpu=15.63ms elapsed=134.61s tid=0x0000020a6a04d800 nid=0x31c0 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
No compile task
Locked ownable synchronizers:
- None
"Sweeper thread" #9 daemon prio=9 os_prio=2 cpu=0.00ms elapsed=134.61s tid=0x0000020a6a955000 nid=0x2e30 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Service Thread" #10 daemon prio=9 os_prio=0 cpu=0.00ms elapsed=134.58s tid=0x0000020a6aae3000 nid=0x1cf4 runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"Common-Cleaner" #11 daemon prio=8 os_prio=1 cpu=0.00ms elapsed=134.57s tid=0x0000020a6aad2800 nid=0x152c in Object.wait() [0x000000ff505fe000]
java.lang.Thread.State: TIMED_WAITING (on object monitor)
at java.lang.Object.wait(java.base@11.0.3/Native Method)
- waiting on <0x0000000711c1f470> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(java.base@11.0.3/ReferenceQueue.java:155)
- waiting to re-lock in wait() <0x0000000711c1f470> (a java.lang.ref.ReferenceQueue$Lock)
at jdk.internal.ref.CleanerImpl.run(java.base@11.0.3/CleanerImpl.java:148)
at java.lang.Thread.run(java.base@11.0.3/Thread.java:834)
at jdk.internal.misc.InnocuousThread.run(java.base@11.0.3/InnocuousThread.java:134)
Locked ownable synchronizers:
- None
"Thread-0" #12 prio=5 os_prio=0 cpu=0.00ms elapsed=134.56s tid=0x0000020a6aad5800 nid=0x2dcc waiting for monitor entry [0x000000ff506ff000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threadDemo.DeadLockDemo$1.run(DeadLockDemo.java:28)
- waiting to lock <0x0000000711c26960> (a java.lang.String)
- locked <0x0000000711c26930> (a java.lang.String)
at java.lang.Thread.run(java.base@11.0.3/Thread.java:834)
Locked ownable synchronizers:
- None
"Thread-1" #13 prio=5 os_prio=0 cpu=0.00ms elapsed=134.56s tid=0x0000020a6aad6000 nid=0x41c waiting for monitor entry [0x000000ff507ff000]
java.lang.Thread.State: BLOCKED (on object monitor)
at threadDemo.DeadLockDemo$2.run(DeadLockDemo.java:41)
- waiting to lock <0x0000000711c26930> (a java.lang.String)
- locked <0x0000000711c26960> (a java.lang.String)
at java.lang.Thread.run(java.base@11.0.3/Thread.java:834)
Locked ownable synchronizers:
- None
"DestroyJavaVM" #14 prio=5 os_prio=0 cpu=125.00ms elapsed=134.56s tid=0x0000020a470c5000 nid=0x3f10 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"VM Thread" os_prio=2 cpu=0.00ms elapsed=134.64s tid=0x0000020a6a044800 nid=0x3b44 runnable
"GC Thread#0" os_prio=2 cpu=0.00ms elapsed=134.67s tid=0x0000020a470dc800 nid=0x2958 runnable
"G1 Main Marker" os_prio=2 cpu=0.00ms elapsed=134.67s tid=0x0000020a4713a800 nid=0x2c50 runnable
"G1 Conc#0" os_prio=2 cpu=0.00ms elapsed=134.67s tid=0x0000020a47142800 nid=0x36cc runnable
"G1 Refine#0" os_prio=2 cpu=0.00ms elapsed=134.66s tid=0x0000020a69f03800 nid=0x4200 runnable
"G1 Young RemSet Sampling" os_prio=2 cpu=0.00ms elapsed=134.66s tid=0x0000020a69f04800 nid=0x1de4 runnable
"VM Periodic Task Thread" os_prio=2 cpu=0.00ms elapsed=134.57s tid=0x0000020a6aae7000 nid=0x578 waiting on condition
JNI global refs: 5, weak refs: 0
Found one Java-level deadlock:
=============================
"Thread-0":
waiting to lock monitor 0x0000020a6a8d9f00 (object 0x0000000711c26960, a java.lang.String),
which is held by "Thread-1"
"Thread-1":
waiting to lock monitor 0x0000020a6a8d9e00 (object 0x0000000711c26930, a java.lang.String),
which is held by "Thread-0"
Java stack information for the threads listed above:
===================================================
"Thread-0":
at threadDemo.DeadLockDemo$1.run(DeadLockDemo.java:28)
- waiting to lock <0x0000000711c26960> (a java.lang.String)
- locked <0x0000000711c26930> (a java.lang.String)
at java.lang.Thread.run(java.base@11.0.3/Thread.java:834)
"Thread-1":
at threadDemo.DeadLockDemo$2.run(DeadLockDemo.java:41)
- waiting to lock <0x0000000711c26930> (a java.lang.String)
- locked <0x0000000711c26960> (a java.lang.String)
at java.lang.Thread.run(java.base@11.0.3/Thread.java:834)
Found 1 deadlock.
```

通过JVM自带工具获取线程dump