【问题标题】:How to capture thread dump programatically using JAVA Code?如何使用 JAVA 代码以编程方式捕获线程转储?
【发布时间】:2016-04-18 17:29:29
【问题描述】:

我想通过 java 代码生成线程转储,我尝试为此使用 ThreadMXBean,但我没有得到正确格式的线程转储,因为我们正在使用 jstack 命令。请任何人提供一些帮助..他们是否有任何其他方式来获取线程转储...使用任何其他 API..我想要的线程转储格式是 -

2015-08-06 05:51:15
Full thread dump Java HotSpot(TM) 64-Bit Server VM (24.51-b03 mixed mode):

"Attach Listener" daemon prio=10 tid=0x00007fdab805d800 nid=0x7a36 waiting on condition [0x0000000000000000]


java.lang.Thread.State: RUNNABLE

"ajp-mco/127.168.121.120:8170-220" daemon prio=10 tid=0x00007fdaa056d000 nid=0x7961 runnable [0x00007fda8bb7a000]


java.lang.Thread.State: RUNNABLE
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:152)
at java.net.SocketInputStream.read(SocketInputStream.java:122)
at org.apache.coyote.ajp.AjpProcessor.read(AjpProcessor.java:1114)
at org.apache.coyote.ajp.AjpProcessor.readMessage(AjpProcessor.java:1196)
at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:436)
at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:420)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:920)
at java.lang.Thread.run(Thread.java:744)

【问题讨论】:

  • 我相信jstack 本身使用ThreadMXBean 来获取此信息。诚然,这与向进程发送kill -3 时得到的线程转储不同。
  • 是的,但是当我使用 ThreadMXBean 时,我无法获得完整的信息,例如 tid、nid、线程是否为守护进程……这些信息我无法通过 threadMXBean。
  • 不幸的是,我不认为 java 公开了获取这些额外细节的方法。

标签: java multithreading mxbean


【解决方案1】:

尝试ManagementFactory.getThreadMXBean().dumpAllThreads(true, true) 使用类似

ThreadMXBean bean = ManagementFactory.getThreadMXBean();
ThreadInfo[] infos = bean.dumpAllThreads(true, true);
System.out.println(Arrays.stream(infos).map(Object::toString)
    .collect(Collectors.joining()));

或者,您也可以通过Runtime.getRuntime.exec() 直接调用jstack

String pid = ManagementFactory.getRuntimeMXBean().getName().replaceAll("[^\\d.]", "");
InputStream in = Runtime.getRuntime().exec(PATH_TO_JSTACK + " " + pid).getInputStream();
System.out.println(IOUtils.toString(InputStream));

这是使用示例程序的输出

ThreadMXBean:

"pool-1-thread-4" Id=14 WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@2d98a335
    at sun.misc.Unsafe.park(Native Method)
    -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@2d98a335
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"pool-1-thread-3" Id=13 WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@2d98a335
    at sun.misc.Unsafe.park(Native Method)
    -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@2d98a335
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"pool-1-thread-2" Id=12 WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@2d98a335
    at sun.misc.Unsafe.park(Native Method)
    -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@2d98a335
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"pool-1-thread-1" Id=11 WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@2d98a335
    at sun.misc.Unsafe.park(Native Method)
    -  waiting on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@2d98a335
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

"Monitor Ctrl-Break" Id=10 RUNNABLE (in native)
    at java.net.DualStackPlainSocketImpl.accept0(Native Method)
    at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
    at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)
    -  locked java.net.SocksSocketImpl@16b98e56
    at java.net.ServerSocket.implAccept(ServerSocket.java:545)
    at java.net.ServerSocket.accept(ServerSocket.java:513)
    at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:90)
    at java.lang.Thread.run(Thread.java:745)

"Attach Listener" Id=5 RUNNABLE

"Signal Dispatcher" Id=4 RUNNABLE

"Finalizer" Id=3 WAITING on java.lang.ref.ReferenceQueue$Lock@7ef20235
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.ReferenceQueue$Lock@7ef20235
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
    at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
    at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" Id=2 WAITING on java.lang.ref.Reference$Lock@27d6c5e0
    at java.lang.Object.wait(Native Method)
    -  waiting on java.lang.ref.Reference$Lock@27d6c5e0
    at java.lang.Object.wait(Object.java:502)
    at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)

"main" Id=1 RUNNABLE
    at sun.management.ThreadImpl.dumpThreads0(Native Method)
    at sun.management.ThreadImpl.dumpAllThreads(ThreadImpl.java:446)
    at Playground.main(Playground.java:25)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)

jstack(通过控制台或通过Runtime.getRuntime().exec()):

Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.65-b01 mixed mode):

"DestroyJavaVM" #15 prio=5 os_prio=0 tid=0x00000000008bd800 nid=0x41c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"pool-1-thread-4" #14 prio=5 os_prio=0 tid=0x0000000016660800 nid=0x166c waiting on condition [0x0000000016dff000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000eb360088> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

"pool-1-thread-3" #13 prio=5 os_prio=0 tid=0x0000000016660000 nid=0x1e34 waiting on condition [0x0000000016cff000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000eb360088> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

"pool-1-thread-2" #12 prio=5 os_prio=0 tid=0x000000001665f000 nid=0x148 waiting on condition [0x0000000016bff000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000eb360088> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

"pool-1-thread-1" #11 prio=5 os_prio=0 tid=0x000000001665b800 nid=0xdf0 waiting on condition [0x0000000016afe000]
   java.lang.Thread.State: WAITING (parking)
        at sun.misc.Unsafe.park(Native Method)
        - parking to wait for  <0x00000000eb360088> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
        at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
        at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
        at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442)
        at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

"Monitor Ctrl-Break" #10 daemon prio=5 os_prio=0 tid=0x000000001641d000 nid=0x2038 runnable [0x00000000169fe000]
   java.lang.Thread.State: RUNNABLE
        at java.net.DualStackPlainSocketImpl.accept0(Native Method)
        at java.net.DualStackPlainSocketImpl.socketAccept(DualStackPlainSocketImpl.java:131)
        at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:409)
        at java.net.PlainSocketImpl.accept(PlainSocketImpl.java:199)
        - locked <0x00000000eb39db18> (a java.net.SocksSocketImpl)
        at java.net.ServerSocket.implAccept(ServerSocket.java:545)
        at java.net.ServerSocket.accept(ServerSocket.java:513)
        at com.intellij.rt.execution.application.AppMain$1.run(AppMain.java:90)
        at java.lang.Thread.run(Thread.java:745)

"Service Thread" #9 daemon prio=9 os_prio=0 tid=0x0000000014a1e000 nid=0x360 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C1 CompilerThread2" #8 daemon prio=9 os_prio=2 tid=0x00000000149c3800 nid=0x89c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread1" #7 daemon prio=9 os_prio=2 tid=0x00000000149c0800 nid=0x2048 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"C2 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x00000000149bd800 nid=0x1aa0 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Attach Listener" #5 daemon prio=5 os_prio=2 tid=0x00000000149bc000 nid=0x108c waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Signal Dispatcher" #4 daemon prio=9 os_prio=2 tid=0x00000000149bb000 nid=0x15a4 runnable [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x00000000023b1000 nid=0x182c in Object.wait() [0x0000000015d1e000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000eb2070b8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x00000000eb2070b8> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164)
        at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209)

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x00000000023ae000 nid=0x21f4 in Object.wait() [0x0000000015c1f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x00000000eb206af8> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:157)
        - locked <0x00000000eb206af8> (a java.lang.ref.Reference$Lock)

"VM Thread" os_prio=2 tid=0x0000000014987000 nid=0x17cc runnable

"GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00000000022d7800 nid=0x2208 runnable

"GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00000000022d9000 nid=0x24c4 runnable

"GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00000000022da800 nid=0x7b0 runnable

"GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00000000022dc000 nid=0x2650 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x000000001634a800 nid=0x271c waiting on condition

JNI global references: 321

【讨论】:

  • 我希望从 java 代码中生成与从 Jstack 获取完全相同的线程转储,以便我们可以使用 Thread dump Analyser 分析转储,而无需任何修改......这可能吗? ?
  • 如果您对Runtime.getRuntime().exec() hack 感到满意,它会为您做到这一点。否则你唯一不能得到的就是原生 ID。
【解决方案2】:

您可以使用Thread.getAllStackTraces() 获取大部分内容。

for (Map.Entry<Thread, StackTraceElement[]> entry : Thread.getAllStackTraces().entrySet()) {
    System.out.println(entry.getKey() + " " + entry.getKey().getState());
    for (StackTraceElement ste : entry.getValue()) {
         System.out.println("\tat " + ste);
    }
    System.out.println();
}

【讨论】:

  • 使用它也无法获得完整的信息,如 tid、nid、线程是否为守护进程...
  • @RishiArora Map 中的键是Thread 对象。它暴露了这些东西。什么是nid
  • @RishiArora 我不确定tid 是什么或它的用途,nid` 是十六进制的进程ID。您可以使用 JNA 获得它,但我不确定您是否需要它。你可以得到Thread.isDaemon()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2021-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多