问题: 针对线上多线程死锁、阻塞,跑着跑着就卡住了;查看线上线程池的状态;
jstack主要用于生成java虚拟机当前时刻的线程快照。线程快照是当前java虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等。 线程出现停顿的时候通过jstack来查看各个线程的调用堆栈,就可以知道没有响应的线程到底在后台做什么事情,或者等待什么资源。
jstack: java堆栈跟踪工具(线程快照和内存快照)
-
执行jstack命令,将得到进程的堆栈信息。我一般使用jstack -l pid来得到长列表,显示其详细信息。
-
有时线程挂起的时候,需要执行jstack -F pid来获取。
-
在实际运行中,往往一次 dump的信息,还不足以确认问题。建议产生三次 dump信息,如果每次 dump都指向同一个问题,我们才确定问题的典型性。
-
堆栈信息只是一种参考,一些正常RUNNING的线程,由于复杂网络环境和IO的影响,也是有问题的,用jstack就无法定位,需要结合对业务代码的理解。
常用命令
jps
top -H -p <pid>
jstack -l <pid>
top -H -p <pid>
1)在当前用户下,列出pid包含的所有线程。查询某个进程中所有的线程信息,cpu使用和内存。
2)线程id(十进制)和线程快照中nid相同(十六进制,操作系统级别的线程id)
3) 关注某个进程中,哪些线程的cpu和内存使用率最高,找到对应的线程快照,并且重点关注线程状态和业务代码。并且关注线程中,是否存在死锁。
1,死锁代码如下
/**
* 测试死锁问题
*/
public class DeadLockDemo {
public static void main(String[] args) {
testDeadLock();
}
private static void testDeadLock() {
ReentrantLock lock1 = new ReentrantLock();
ReentrantLock lock2 = new ReentrantLock();
Thread thread1 = new Thread(new Runnable() {
@Override
public void run() {
lock1.lock();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock2.lock();
}
});
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
lock2.lock();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock1.lock();
}
});
thread1.setName("thread1");
thread2.setName("thread2");
System.out.println("启动线程");
thread1.start();
thread2.start();
}
}
2,线程快照如下:
命令:jps获取进程编号,jstack -l 82595 >> thread.txt
使用jstack查看服务进程的线程情况
2021-05-19 15:29:10
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.291-b10 mixed mode):
"Attach Listener" #14 daemon prio=9 os_prio=31 tid=0x00007f8b2c45c800 nid=0x9c03 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"DestroyJavaVM" #13 prio=5 os_prio=31 tid=0x00007f8b2c015000 nid=0x2403 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"thread2" #12 prio=5 os_prio=31 tid=0x00007f8b1c016800 nid=0x9e03 waiting on condition [0x000000