Java线程之Dump

什么是线程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

原文地址:https://www.cnblogs.com/liukaifeng/p/10052647.html