概述
jstack是jdk自帶的線程堆棧分析工具,使用該命令可以查看或?qū)С?Java 應(yīng)用程序中線程堆棧信息。
Jstack 用法
參數(shù)說明:
-l 長列表. 打印關(guān)于鎖的附加信息,例如屬于java.util.concurrent 的 ownable synchronizers列表.
-F 當(dāng)’jstack [-l] pid’沒有相應(yīng)的時候強制打印棧信息
-m 打印java和native c/c++框架的所有棧信息.
-h | -help 打印幫助信息
pid 需要被打印配置信息的java進程id,可以用jps查詢.
Jstack 使用
通過使用 jps 命令獲取需要監(jiān)控的進程的pid,然后使用 jstack pid 命令查看線程的堆棧信息。
通過 jstack 命令可以獲取當(dāng)前進程的所有線程信息。
每個線程堆中信息中,都可以查看到 線程ID、線程的狀態(tài)(wait、sleep、running 等狀態(tài))、是否持有鎖信息等。
死鎖示例
下面通過一個例子,來演示 jstack 檢查死鎖的一個例子,代碼如下:
public static void deathLock() {
Thread t1 = new Thread() {
@Override
public void run() {
try {
lock1.lock();
TimeUnit.SECONDS.sleep(1);
lock2.lock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t2 = new Thread() {
@Override
public void run() {
try {
lock2.lock();
TimeUnit.SECONDS.sleep(1);
lock1.lock();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
t1.setName("mythread1");
t2.setName("mythread2");
t1.start();
t2.start();
}
使用 jstack -l pid 查看線程堆棧信息,發(fā)現(xiàn)在堆棧信息最后面檢查出了一個死鎖。如下圖
可以清楚的看出 mythread2 等待 這個鎖 “0x00000000d6eb82d0”,這個鎖是由于mythread1線程持有。
mythread1線程等待這個鎖“0x00000000d6eb8300”,這個鎖是由mythread2線程持有。
“mythread1”線程堆棧信息如下:
可以看出當(dāng)前線程持有“0x00000000d6eb82d0”鎖,等待“0x00000000d6eb8300”的鎖
“mythread2”線程堆棧信息如下:
“mythread2”的堆棧信息中可以看出當(dāng)前線程持有“0x00000000d6eb8300”鎖,等待“0x00000000d6eb82d0”的鎖。