jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息。
命令格式
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) 可能是产生core dump的java可执行程序,连接core文件
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
- pid 为需要打印配置信息的Java进程号
- -F当’jstack [-l] pid’没有相应的时候强制打印栈信息
- -l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
- -m打印java和native c/c++框架的所有栈信息.
- -h | -help打印帮助信息
使用示例 检查死锁
- 运行一个产生死锁的程序
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author zxg
*/
public class TestDeadLock {
private static ReentrantLock lock1 = new ReentrantLock();
private static ReentrantLock lock2 = new ReentrantLock();
public static void main(String[] args) {
Thread t1 = new Thread(() -> {
lock1.lock();
System.out.println(Thread.currentThread().getName() + " get lock1");
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + " try to get lock2");
lock2.lock();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock1.unlock();
}
}, "thread1");
Thread t2 = new Thread(() -> {
lock2.lock();
System.out.println(Thread.currentThread().getName() + " get lock2");
try {
TimeUnit.SECONDS.sleep(1);
System.out.println(Thread.currentThread().getName() + " try to get lock1");
lock1.lock();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock2.unlock();
}
}, "thread2");
t1.start();
t2.start();
}
}
程序造成死锁没有停止。
-
查看该java进程号
Ctrl+Shift+Esc
-
统计线程数
jstack -l 7776 | grep 'java.lang.Thread.State' | wc -l
-
jstack查看输出