一 点睛
jstack(JVM Stack Trace):用于生成虚拟机指定进程当前时刻的线程快照(虚拟机堆栈跟踪)。线程快照就是当前虚拟机内指定进程的每一条线程正在执行的方法堆栈的集合。
生成线程快照的作用:可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用 jstack 显示各个线程调用的堆栈情况。
官方帮助文档:https://docs.oracle.com/en/java/javase/11/tools/jstack.html
在 thread dump 中,要留意下面几种状态
-
死锁,Deadlock(重点关注)
-
等待资源,Waiting on condition(重点关注)
-
等待获取监视器,Waiting on monitor entry(重点关注)
-
阻塞,Blocked(重点关注)
-
执行中,Runnable
-
暂停,Suspended
-
对象等待中,Object.wait() 或 TIMED_WAITING
-
停止,Parked
F:\svn\19_byzb_back\branches\JVMDemo3>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)
Options:
-F to force a thread dump. Use when jstack <pid> does not respond (process is hung)
-m to print both java and native frames (mixed mode)
-l long listing. Prints additional information about locks
-h or -help to print this help message
option 参数 |
作用 |
-F |
当正常输出的请求不被响应时,强制输出线程堆栈 |
-l |
除堆栈外,显示关于锁的附加信息 |
-m |
如果调用本地方法的话,可以显示 C/C++的堆栈 |
二 实战——定位死锁问题
1 代码
package chaper02;
/**
* @className: ThreadDeadLock
* @description: 线程死锁
* @date: 2021/8/22
*/
public class ThreadDeadLock {
public static void main(String[] args) {
StringBuilder s1 = new StringBuilder();
StringBuilder s2 = new StringBuilder();
new Thread() {
public void run() {
synchronized (s1) {
s1.append("a");
s2.append("1");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s2) {
s1.append("b");
s2.append("2");
System.out.println(s1);
System.out.println(s2);
}
}
}
}.start();
new Thread() {
public void run() {
synchronized (s2) {
s1.append("c");
s2.append("3");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (s1) {
s1.append("d");
s2.append("4");
System.out.println(s1);
System.out.println(s2);
}
}
}
}.start();
}
}
2 测试
F:\svn\19_byzb_back\branches\JVMDemo3>jstack 16324
2021-08-22 15:45:20
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.251-b08 mixed mode):
"DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x00000000024ee800 nid=0x4d04 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Thread-1" #13 prio=5 os_prio=0 tid=0x000000001dd12000 nid=0x3efc waiting for monitor entry [0x000000001ec6f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at chaper02.ThreadDeadLock$2.run(ThreadDeadLock.java:48)
- waiting to lock <0x00000007708001a8> (a java.lang.StringBuilder)
- locked <0x00000007708001f0> (a java.lang.StringBuilder)
"Thread-0" #12 prio=5 os_prio=0 tid=0x000000001dd0f000 nid=0x4874 waiting for monitor entry [0x000000001eb6f000]
java.lang.Thread.State: BLOCKED (on object monitor)
at chaper02.ThreadDeadLock$1.run(ThreadDeadLock.java:25)
- waiting to lock <0x00000007708001f0> (a java.lang.StringBuilder)
- locked <0x00000007708001a8> (a java.lang.StringBuilder)
"Service Thread" #11 daemon prio=9 os_prio=0 tid=0x000000001dcfa800 nid=0x3a5c runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C1 CompilerThread3" #10 daemon prio=9 os_prio=2 tid=0x000000001dc53000 nid=0x4fd4 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread2" #9 daemon prio=9 os_prio=2 tid=0x000000001dc52800 nid=0x4db4 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" #8 daemon prio=9 os_prio=2 tid=0x000000001dc4f000 nid=0x445c waiting on condition [0x0000000000000000]</