有的时候,我们想知道我们的java哪些是阻塞的,如果我们用jstack命令进行线程栈快照,我们只能知晓当前时刻点的线程状态,但是线程什么时候创建的,什么时候销毁的,全然不知。
思路
我们可以使用操作系统的ps命令来观察系统线程的创建时间,将线程的id和jstack的线程栈关联,即可知道我们jvm的当前线程栈中某个线程是何时创建的。
操作
- 使用
jstack -l pid > dump.log
命令dump出线程栈 - 找到你关注线程的
nid
,例如:
"Thread-7" #30 daemon prio=5 os_prio=0 tid=0x00002aaac9688800 nid=0x6945 runnable [0x00000000429c5000]
^^^^^^
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPoll.epollWait(Native Method)
at sun.nio.ch.EPollPort$EventHandlerTask.poll(EPollPort.java:194)
at sun.nio.ch.EPollPort$EventHandlerTask.run(EPollPort.java:268)
at java.lang.Thread.run(Thread.java:745)
- 将16进制的
nid
转换成10进制(直接使用bash的printf指令)
root@localhost:/# printf "%d\n" 0x6945 26949
- 使用命令
ps -Lo tid,lstart <PID> | grep <TID>
来找到线程的创建时间
root@localhost:/# ps -Lo tid,lstart 1 | grep 26949
26949 Fri Jan 29 19:02:42 2021
root@localhost:/# ps -Lo tid,etime,lstart -p 1 | grep 26949
26949 27:06 Sat Jan 30 02:07:12 2021
如你所见你关注线程的创建时间即可得到。
我计划搞个脚本,可以将创建时间还原到线程栈分析里面去,例如按照创建时间来看线程栈,看起来更直观。
参考资料: