Java线程和多线程(八)——Thread Dump

Java Thread Dump用于列出JVM中所有活动线程的状态,尤其在性能瓶颈和死锁分析时非常有用。本文介绍了通过VisualVM Profiler、jstack、kill -3命令以及Java 8的jcmd生成Thread Dump的方法,并展示了Thread Dump包含的线程信息,如名字、优先级、状态和堆栈跟踪,帮助诊断性能问题。

Java的Thread Dump就是列出JVM中所有激活状态的线程。

Java Thread Dump

Java Thread Dump在分析应用性能瓶颈和死锁的时候,是非常有效的。

下面将介绍多种不同的方式来获取Java程序的Thread Dump信息。这些指令在*nix型的操作系统下是有效的,但是在Windows下面,采取的方式会有一些不同。(主要是Pid信息获取不太一致,可通过任务管理器获取)

  1. VisualVM Profiler:如果开发者需要分析程序变慢的原因,那么必然要使用profiler。我们可以通过VisulaVM Profiler工具很容易的从运行的线程获取Thread Dump。你所需要的就是右键运行的进行,然后点击Thread Dump来获得这个信息。
    这里写图片描述
  2. jstack:Java本身就自带的jstack工具,我们可以通过Java线程来直接生成Thread Dump。
    1. 受限找到Java进程的PID,可以通过ps -eaf | grep java命令来获取。
    2. 然后运行jstack工具,jstack PID来生成Thread Dump到控制台,当然,也可以通过重定向,将Thread Dump信息的输出通过命令jstack PID >> thread.dump写入thread.dump这个文本当中。

  3. 我们可以通过kill -3 PID命令来生成Thread Dump信息。这种方式和其它的生成Thread Dump的方式略有不同,当执行了kill命令的时候,Thread Dump信息会直接输出到控制台。所以,如果Java程序的System.out是控制台的话,Thread Dump的信息就会打印到控制台。如果Java的程序时一个Tomcat的服务程序,System.out将变成catalina.out文件,那时,Thread Dump会打印到catalina.out这个文件之中。
  4. Java 8引入了jcmd工具箱,开发者如果使用的是Java 8或者更高的版本的话,可以用之来替换掉jstack。命令行与jstack很类似:jcmd PID Thread.print

上面的四种方式都可以用来在Java中生成Thread Dump的信息。通常,我推荐使用jstack或者jcmd命令来生成Thread Dump信息来分析。当然,无论你使用什么样的方式,最后的Thread Dump的信息都是一样的。

Java Thread Dump举例

我将自己写的一个Tomcat程序运行Thread Dump,结果如下:

$ jcmd 4428 Thread.print
4428:
2016-09-27 22:42:29
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.65-b01 mixed mode):

"ajp-nio-8009-AsyncTimeout" #39 daemon prio=5 os_prio=0 tid=0x000000001d4c4000 nid=0x34c4 waiting on condition [0x000000002ca1f000]
   java.lang.Thread.State: TIMED_WAITING (sleeping)
        at java.lang.Thread.sleep(Native Method)
        at org.apache.coyote.AbstractProtocol$AsyncTimeout.run(AbstractProtocol.java:1080)
        at java.lang.Thread.run(Thread.java:745)

"ajp-nio-8009-Acceptor-0" #38 daemon prio=5 os_prio=0 tid=0x000000001d4c6800 nid=0x34c0 runnable [0x000000002c91f000]
   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 <0x0000000080b2bfb0> (a java.lang.Object)
        at org.apache.tomcat.util.net.NioEndpoint$Acceptor.run(NioEndpoint.java:508)
        at java.lang.Thread.run(Thread.java:745)

"ajp-nio-8009-ClientPoller-1" #37 daemon prio=5 os_prio=0 tid=0x000000001d4c3800 nid=0x34bc runnable [0x000000002c81e000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
        at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
        - locked <0x00000000829ecd28> (a sun.nio.ch.Util$2)
        - locked <0x00000000829ecd18> (a java.util.Collections$UnmodifiableSet)
        - locked <0x00000000829ecba8> (a sun.nio.ch.WindowsSelectorImpl)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
        at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:843)
        at java.lang.Thread.run(Thread.java:745)

"ajp-nio-8009-ClientPoller-0" #36 daemon prio=5 os_prio=0 tid=0x000000001d4c5800 nid=0x34b8 runnable [0x000000002b72f000]
   java.lang.Thread.State: RUNNABLE
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll0(Native Method)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.poll(WindowsSelectorImpl.java:296)
        at sun.nio.ch.WindowsSelectorImpl$SubSelector.access$400(WindowsSelectorImpl.java:278)
        at sun.nio.ch.WindowsSelectorImpl.doSelect(WindowsSelectorImpl.java:159)
        at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86)
        - locked <0x00000000829ee720> (a sun.nio.ch.Util$2)
        - locked <0x00000000829ee710> (a java.util.Collections$UnmodifiableSet)
        - locked <0x00000000829ee5a0> (a sun.nio.ch.WindowsSelectorImpl)
        at sun.nio.ch.SelectorImpl.select(SelectorImpl.java:97)
        at org.apache.tomcat.util.net.NioEndpoint$Poller.run(NioEndpoint.java:843)
        at java.lang
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值