在排查java应用的时候,常常会dump线程栈来观察各个线程的状态方便定位问题,这里简单描述一下如何阅读通过jstack打印出来的线程内容。
jstack以线程为单位打印内容,现在我们已线程为单位来分析:
第一行:$1-线程名称 $2-优先级 $3-java线程id $4-native线程id $5-状态描述 $6-线程栈起始地址
第二行:线程状态
以下行:线程栈具体内容
线程状态(java.lang.Thread.State)
RUNNABLE
"Attach Listener" daemon prio=5 tid=0x00007f87fa858000 nid=0x380b waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
注意:如果线程阻塞于socket操作,线程也处于RUNNABLE,这个时候需要多dump几次线程,观察该线程是否一致处于socket操作
TIMED_WAITING
* Thread.sleep *
"sleep-thread" prio=5 tid=0x00007ffcab0ac800 nid=0x5303 waiting on condition [0x0000000117566000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at Main$1.run(Main.java:31)
at java.lang.Thread.run(Thread.java:745)
BLOCKED
* 等待监视器,处于blocked状态 *
"block-thread" prio=5 tid=0x00007fc18b0d7800 nid=0x5703 waiting for monitor entry [0x0000000117dd8000]
java.lang.Thread.State: BLOCKED (on object monitor)
at Main$2.run(Main.java:43)
- waiting to lock <0x00000007aab6fe90> (a java.lang.String)
at java.lang.Thread.run(Thread.java:745)
WAITING
* 在一个同步块中调用了Object.wait()处于等待 *
"objectWait" prio=5 tid=0x00007f87f9063000 nid=0x5503 in Object.wait() [0x000000011372c000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007aab6ffd8> (a java.lang.String)
at java.lang.Object.wait(Object.java:503)
at Main$2.run(Main.java:47)
- locked <0x00000007aab6ffd8> (a java.lang.String)
at java.lang.Thread.run(Thread.java:745)
场景
CPU飙高
定位java进程:jps -v
定位java线程:top -Hp [pid]
将线程id转乘16进制:printf "%x\n" [nid]
在jstack dumps文件内定位线程
观察线程栈,基本能看出线程cpu使用飙高的原因