概述
jstack 是 jdk 自带的线程堆栈分析工具,使用改命令可以查看或导出 Java 应用程序中线程堆栈信息.
Jstack 用法
image
参数说明:
-l 长列表. 打印关于锁的附加信息, 例如属于 java.util.concurrent 的 ownable synchronizers 列表.
-F 当'jstack [-l] pid'没有相应的时候强制打印栈信息
-m 打印 java 和 native c/c++ 框架的所有栈信息.
-h | -help 打印帮助信息
pid 需要被打印配置信息的 java 进程 id, 可以用 jps 查询.
Jstack 使用
通过使用 jps 命令获取需要监控的进程的 pid,然后使用 jstack pid 命令查看线程的堆栈信息.
image
通过 jstack 命令可以获取当前进程的所有线程信息.
每个线程堆中信息中,都可以查看到 线程 ID,线程的状态(wait,sleep,running 等状态),是否持有锁信息等.
死锁示例
下面通过一个例子,来演示 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 查看线程堆栈信息,发现在堆栈信息最后面检查出了一个死锁.如下图
可以清楚的看出 mythread2 等待 这个锁 "0x00000000d6eb82d0",这个锁是由于 mythread1 线程持有.
mythread1 线程等待这个锁 "0x00000000d6eb8300", 这个锁是由 mythread2 线程持有.
"mythread1" 线程堆栈信息如下:
可以看出当前线程持有 "0x00000000d6eb82d0" 锁,等待 "0x00000000d6eb8300" 的锁
"mythread2" 线程堆栈信息如下:
"mythread2" 的堆栈信息中可以看出当前线程持有 "0x00000000d6eb8300" 锁,等待 "0x00000000d6eb82d0" 的锁.
来源: http://www.jianshu.com/p/025cb069cb69