jstack-查找死锁,线程堆栈分析工具
jstack是jdk自带的线程堆栈分析工具,使用该命令可以查看或导出 java 应用程序中线程堆栈信息。jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以
目录
jstack用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。 如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。
1、jstack-查找死锁
用jstack加进程id查找死锁,见如下示例
public class DeadLockTest {
private static Object lock1 = new Object();
private static Object lock2 = new Object();
public static void main(String[] args) {
new Thread(() -> {
synchronized (lock1) {
try {
System.out.println("thread1 begin");
Thread.sleep(5000);
} catch (InterruptedException e) {
}
synchronized (lock2) {
System.out.println("thread1 end");
}
}
}).start();
new Thread(() -> {
synchronized (lock2) {
try {
System.out.println("thread2 begin");
Thread.sleep(5000);
} catch (InterruptedException e) {
}
synchronized (lock1) {
System.out.println("thread2 end");
}
}
}).start();
System.out.println("main thread end");
}
}
// jstack id
- "Thread-1" 线程名
- prio=5 优先级=5
- tid=0x000000002a4be800 线程id
- nid=0x10f4 线程对应的本地线程标识nid(十六进制)
- java.lang.Thread.State: BLOCKED 线程状态
还可以用jvisualvm自动检测死锁
2、jstack找出占用cpu最高的线程堆栈信息
测试代码:
public class Math {
public static final int initData = 666;
public int compute() {
int a = 1;
int b = 2;
int c = (a + b) * 10;
return c;
}
public static void main(String[] args) {
Math math = new Math();
while (true){
math.compute(); //不停循环计算
}
}
}
编译成字节码后,使用java命令执行,注意:代码中不能有中文,也不能指定包名
解决:Error: Could not find or load main class xxx
//解决问题思路:
1、使用命令top / top -p pid ,显示你的java进程的内存情况,pid是你的java进程号,比如19663
2、按H(大写),获取每个线程的内存情况
3、找到内存和cpu占用最高的线程tid,比如19664
4、转为十六进制得到 0x4cd0,此为线程id的十六进制表示
5、执行 jstack 19663 | grep -A 10 4cd0,得到线程堆栈信息中 4cd0 这个线程所在行的后面10行,从堆栈中可以发现导致cpu飙高的调用方法
6、查看对应的堆栈信息找出可能存在问题的代码
更多推荐
所有评论(0)