Java堆栈跟踪 - jstack

jstack能打印jvm进程中的线程堆栈信息。

jstack [ option ] pid
jstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP

线程状态

Java线程的6种状态:

Thread.State

NEW

尚未启动时的状态。

RUNNABLE

可运行状态。

处于可运行状态的线程,可能正在执行,也可能正在等待操作系统资源,如:处理器。

BLOCKED

阻塞状态。

处于阻塞状态的线程,等待拿到同步锁后进入同步代码块,或重新进入同步代码块。

此状态的线程通常是调用了如下方法:

Object.wait();

WAITING

等待状态。

线程正在等待另一个线程执行特定的操作。如:

线程在一个对象上调用wait()方法,等待另一个线程在该对象上调用notify()或notifyall()方法。

此状态的线程通常调用了以下方法,如:

Object.wait()
Thread.join()
LockSupport.park()

说明:这种状态通常是调用api时没有设置超时时间。

TIMED_WAITING

定时等待状态。

此状态的线程通常调用了以下方法:

Thread.sleep(long millis)
Object.wait(long)
Thread.join(long)
LockSupport.parkNanos(long nanos)
LockSupport.parkUntil(long deadline)

说明:这种状态通常是调用api时设置了超时时间。

TERMINATED

终止状态。线程已执行完。

查看线程状态

查看jvm进程:

jps

查看线程信息

jstack <pid>

如:

jstack -l 15877

jstack dump文件

jstask dum在特定时间记录特定文件或应用程序状态。

应关注的状态:

Deadlock:死锁(重点关注) 

Waiting on condition:等待资源(重点关注) 

Waiting on monitor entry:等待获取对象锁(重点关注)

Blocked:阻塞(重点关注)  

Runnable:执行中

Suspended:暂停

Object.wait() 或 TIMED_WAITING:等待

Parked:停止

排查流程

1、获取java应用进程pid:

[root@master ~]# jps
15877 app.jar
16559 Jps

2、查看指定进程下最耗资源的线程:

[root@master ~]# top Hp 15877

 PID USER   PR NI  VIRT  RES  SHR S %CPU %MEM   TIME+ COMMAND
15877 root   20  0 2435068 115884 14848 S 0.0 11.4  0:00.00 java
15880 root   20  0 2435068 115884 14848 S 0.0 11.4  0:01.10 java
15881 root   20  0 2435068 115884 14848 S 0.0 11.4  0:01.30 VM Thread

3、将线程id转换成16进制:

[root@master ~]# printf "%x\n" 15881
3e09

4、从活动线程中找到指定线程:

[root@master ~]# jstack -l 15877|grep 3e09
"VM Thread" os_prio=0 cpu=1325.50ms elapsed=38983.19s tid=0x00007ff8700f6000 nid=0x3e09 runnable

说明:运行中的线程。

等待中的线程:

[root@master ~]# jstack -l 15877|grep 6ada
"pool-1-thread-1" #92 prio=5 os_prio=0 cpu=1.77ms elapsed=25169.36s tid=0x00007ff850315000 nid=0x6ada waiting on condition [0x00007ff8444c5000]
[root@master ~]# jstack -l 15877|grep 0x3e27
"Abandoned connection cleanup thread" #23 daemon prio=5 os_prio=0 cpu=862.93ms elapsed=39166.31s tid=0x00007ff850069000 nid=0x3e27 in Object.wait() [0x00007ff844fcc000]