什么是线程dump
Java Thread dump记录了线程在jvm中的执行信息,可以看成是线程活动的日志。Java线程转储文件有助于分析应用程序和死锁情况中的瓶颈。
如何获取线程转储文件
在这里,我们将学习为java程序生成线程转储的多种方法,这些指令对于linux操作系统是有效的,但是在windows中,这些步骤可能有些不同。
1.使用VisualVM Profiler
右键选择线程Dump便会自动生成线程转储文件,当然你也可以连接远程机器对其进行监控和分析
2.jstack
jdk自带的工具jstack通过它我们也可以生成应用程序的线程转储文件,只需要两步即可完成:
1>找到应用程序的进程ID
ps -eaf | grep java
2> 输出线程转储信息到文件或控制台
jstack PID >> mydumps.tdump
jstack PID
3.kill -3 PID
该方法与其它生成线程转储文件的方法略有不同,当kill命令发出时,线程存储文件将在该应用程序的外部生成,如果java程序是一个Tomcat服务器,带有系统输出文件catalina.out,那么将在此文件中生成线程转储
4.jcmd
jdk8中介绍了jcmd工具,在jdk8及以上环境下,可以使用此命令生成线程转储文件
命令是:
jcmd PID Thread.print
线程转储文件说明
"Attach Listener" #44 daemon prio=9 os_prio=0 tid=0x00007f88b0001800 nid=0xa89 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"ajp-nio-8009-AsyncTimeout" #42 daemon prio=5 os_prio=0 tid=0x00007f88dc49c000 nid=0xa7e waiting on condition [0x00007f88c8470000]
java.lang.Thread.State: TIMED_WAITING (sleeping)
at java.lang.Thread.sleep(Native Method)
at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1211)
at java.lang.Thread.run(Thread.java:748)
"ajp-nio-8009-Acceptor-0" #41 daemon prio=5 os_prio=0 tid=0x00007f88dc3b8800 nid=0xa7d runnable [0x00007f88c8571000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.ServerSocketChannelImpl.accept0(Native Method)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:422)
at sun.nio.ch.ServerSocketChannelImpl.accept(ServerSocketChannelImpl.java:250)
- locked <0x00000000f5f08d48> (a java.lang.Object)
at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:453)
at java.lang.Thread.run(Thread.java:748)
"ajp-nio-8009-ClientPoller-0" #40 daemon prio=5 os_prio=0 tid=0x00007f88dc3b6800 nid=0xa7c runnable [0x00007f88c8672000]
java.lang.Thread.State: RUNNABLE
at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
at sun.nio.ch.EPollArrayWrapper.poll(EPollArrayWrapper.java:269)
at sun.nio.ch.EPollSelectorImpl.doSelect(EPollSelectorImpl.java:93)
at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
- locked <0x00000000f0e02b08> (a sun.nio.ch.Util$3)
- locked <0x00000000f0e02af8> (a java.util.Collections$UnmodifiableSet)
- locked <0x00000000f0e029e0> (a sun.nio.ch.EPollSelectorImpl)
at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:785)
at java.lang.Thread.run(Thread.java:748)
线程转储是所有线程的列表,每个条目显示关于线程的信息,其中包括按照执行的顺序进行跟踪的信息。线程转储文件中的信息包含以下几个部分:
1、线程名字
2、线程优先级
3、线程ID
4、线程状态:显示当前线程状态,例如:RUNNABLE, WAITING, 5、BLOCKED,在分析死锁的同时,查找他们试图获取锁的阻塞线程和资源
6、堆栈信息:在这里如果线程在等待任何锁,我们可以看到线程获得的锁的地方
翻译自:https://www.journaldev.com/1053/java-thread-dump-visualvm-jstack-kill-3-jcmd