jstack的使用

目录

一、介绍

二、命令格式

三、使用实例

1、jstack -F 6800

2、jstack -l 6800

3、jstack -m 6800

四、线程与Monitor



一、介绍

  • jstack是java虚拟机自带的一种堆栈跟踪工具。jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈
  • jstack作用:用于显示指定进程内线程的信息。

二、命令格式

  • 语法:
jstack [option] <pid>
  •  说明:

1、option:命令选项,常用选项如下:

(1)-F:当’jstack [-l] pid’没有相应的时候强制打印栈信息,如果直接jstack无响应时,用于强制jstack),一般情况不需要使用

(2)-l长列表: 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表,会使得JVM停顿得长久得多(可能会差很多倍,比如普通的jstack可能几毫秒和一次GC没区别,加了-l 就是近一秒的时间),-l 建议不要用。一般情况不需要使用

(3)-m:打印java和native c/c++框架的所有栈信息.可以打印JVM的堆栈,显示上Native的栈帧,一般应用排查不需要使用

2、pid:进程id


三、使用实例


1、jstack -F 6800

C:\Users\Van>jstack -F 6800
Attaching to process ID 6800, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 25.131-b11
Deadlock Detection:

No deadlocks found.

Thread 1: (state = BLOCKED)


Thread 10: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - java.lang.Object.wait() @bci=2, line=502 (Interpreted frame)
 - sun.TimeThread.run() @bci=13, line=17 (Interpreted frame)


Thread 6: (state = BLOCKED)


Thread 5: (state = BLOCKED)


Thread 4: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - java.lang.ref.ReferenceQueue.remove(long) @bci=59, line=143 (Interpreted frame)
 - java.lang.ref.ReferenceQueue.remove() @bci=2, line=164 (Interpreted frame)
 - java.lang.ref.Finalizer$FinalizerThread.run() @bci=36, line=209 (Interpreted frame)


Thread 3: (state = BLOCKED)
 - java.lang.Object.wait(long) @bci=0 (Interpreted frame)
 - java.lang.Object.wait() @bci=2, line=502 (Interpreted frame)
 - java.lang.ref.Reference.tryHandlePending(boolean) @bci=54, line=191 (Interpreted frame)
 - java.lang.ref.Reference$ReferenceHandler.run() @bci=1, line=153 (Interpreted frame)

分析:

(1)“Service Thread”中的 daemon表示线程是否是守护线程;

(2) “C1 Compiler Thread()”中的prio指线程的优先级;

(3) "Attach Listener"中

         ①os_prio指该线程对应的操作系统线程的优先级;

         ②tid:java中线程编号;

         ③nid:即native id,该线程对应的操作系统中本地线程编号,每一个java线程都有一个对应的操作系统线程。

         ④ "Finalizer"指线程名;

         ⑤下一行中的java.lang.Thread.State:指线程状态;

         ⑥WAITING (on object monitor):表示该线程处于等待状态,括号中的内容说明了导致等待的原因。


2、jstack -l 6800

C:\Users\Van>jstack -l 6800
2019-07-21 18:36:04
Full thread dump Java HotSpot(TM) Client VM (25.131-b11 mixed mode, sharing):

"DestroyJavaVM" #9 prio=5 os_prio=0 tid=0x0085c400 nid=0x10a4 waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"Thread-0" #8 prio=5 os_prio=0 tid=0x15cb0c00 nid=0x1380 in Object.wait() [0x15f8f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x09dd2b58> (a java.lang.Object)
        at java.lang.Object.wait(Object.java:502)
        at sun.TimeThread.run(Test.java:17)
        - locked <0x09dd2b58> (a java.lang.Object)

   Locked ownable synchronizers:
        - None

"Service Thread" #7 daemon prio=9 os_prio=0 tid=0x026f7000 nid=0x19f4 runnable [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

"C1 CompilerThread0" #6 daemon prio=9 os_prio=2 tid=0x026f0000 nid=0x260 waiting on condition [0x00000000]
   java.lang.Thread.State: RUNNABLE

   Locked ownable synchronizers:
        - None

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

   Locked ownable synchronizers:
        - None

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

   Locked ownable synchronizers:
        - None

"Finalizer" #3 daemon prio=8 os_prio=1 tid=0x026d3400 nid=0x1bd4 in Object.wait() [0x1543f000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x09d57928> (a java.lang.ref.ReferenceQueue$Lock)
        at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143)
        - locked <0x09d57928> (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)

   Locked ownable synchronizers:
        - None

"Reference Handler" #2 daemon prio=10 os_prio=2 tid=0x02676800 nid=0x1cf0 in Object.wait() [0x153af000]
   java.lang.Thread.State: WAITING (on object monitor)
        at java.lang.Object.wait(Native Method)
        - waiting on <0x09d56280> (a java.lang.ref.Reference$Lock)
        at java.lang.Object.wait(Object.java:502)
        at java.lang.ref.Reference.tryHandlePending(Reference.java:191)
        - locked <0x09d56280> (a java.lang.ref.Reference$Lock)
        at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153)

   Locked ownable synchronizers:
        - None

"VM Thread" os_prio=2 tid=0x02672c00 nid=0x1004 runnable

"VM Periodic Task Thread" os_prio=2 tid=0x15ca0800 nid=0x34d4 waiting on condition

JNI global references: 6

3、jstack -m 6800

C:\Users\Van>jstack -m 6800
Attaching to process ID 6800, please wait...
Debugger attached successfully.
Client compiler detected.
JVM version is 25.131-b11
Deadlock Detection:

No deadlocks found.

----------------- 0 -----------------
0x77811d6c      ntdll!ZwWaitForSingleObject + 0xc
0x76b0d0c2      KERNELBASE!WaitForSingleObject + 0x12
0x00cc5055      javaw + 0x5055
0x00cc33aa      javaw + 0x33aa
0x00cc4497      javaw + 0x4497
0x00cc3638      javaw + 0x3638
----------------- 1 -----------------
0x77811d6c      ntdll!ZwWaitForSingleObject + 0xc
0x76b0d0c2      KERNELBASE!WaitForSingleObject + 0x12
0x54a8fcd9      jvm!_JVM_FindSignal@4 + 0x2959
0x54a2cbd1      jvm!JVM_GetThreadStateNames + 0x4f021
0x54a2cf5a      jvm!JVM_GetThreadStateNames + 0x4f3aa
0x54a4dab1      jvm!JVM_GetThreadStateNames + 0x6ff01
0x549ab575      jvm!JNI_GetCreatedJavaVMs + 0x5905
0x00cc20ad      javaw + 0x20ad
0x00ccaebf      javaw + 0xaebf
0x00ccaf49      javaw + 0xaf49
0x76968744      KERNEL32!BaseThreadInitThunk + 0x24
0x7780584d      ntdll!RtlGetAppContainerNamedObjectPath + 0xfd
0x7780581d      ntdll!RtlGetAppContainerNamedObjectPath + 0xcd
----------------- 2 -----------------
0x77811d6c      ntdll!ZwWaitForSingleObject + 0xc
0x76b0d0c2      KERNELBASE!WaitForSingleObject + 0x12
0x54a8fbcd      jvm!_JVM_FindSignal@4 + 0x284d
0x54a2cbdc      jvm!JVM_GetThreadStateNames + 0x4f02c
0x54a2cf0c      jvm!JVM_GetThreadStateNames + 0x4f35c
0x54a52b41      jvm!JVM_GetThreadStateNames + 0x74f91
0x54a52f02      jvm!JVM_GetThreadStateNames + 0x75352
0x54a92ec6      jvm!_JVM_FindSignal@4 + 0x5b46
0x5a94c556      msvcr100!_endthreadex + 0x3a
0x5a94c600      msvcr100!_endthreadex + 0xe4
0x76968744      KERNEL32!BaseThreadInitThunk + 0x24
0x7780584d      ntdll!RtlGetAppContainerNamedObjectPath + 0xfd
0x7780581d      ntdll!RtlGetAppContainerNamedObjectPath + 0xcd
----------------- 3 -----------------
0x77811d6c      ntdll!ZwWaitForSingleObject + 0xc
0x76b0d0c2      KERNELBASE!WaitForSingleObject + 0x12
0x54a8fcd9      jvm!_JVM_FindSignal@4 + 0x2959
0x54a31c11      jvm!JVM_GetThreadStateNames + 0x54061
0x54a47744      jvm!JVM_GetThreadStateNames + 0x69b94
0x549d2155      jvm!_JVM_MonitorWait@16 + 0x95
0x0275d3d3      * java.lang.Object.wait(long) bci:0 (Interpreted frame)
0x02754854      * java.lang.Object.wait() bci:2 line:502 (Interpreted frame)
0x02754854      * java.lang.ref.Reference.tryHandlePending(boolean) bci:54 line:191 (Interpreted frame)
0x02754300      * java.lang.ref.Reference$ReferenceHandler.run() bci:1 line:153 (Interpreted frame)
0x02750697      <StubRoutines>
0x54a2af45      jvm!JVM_GetThreadStateNames + 0x4d395
0x54af13ae      jvm!_JVM_FindSignal@4 + 0x6402e
0x54a2afde      jvm!JVM_GetThreadStateNames + 0x4d42e
0x54a2b166      jvm!JVM_GetThreadStateNames + 0x4d5b6
0x54a2b1d7      jvm!JVM_GetThreadStateNames + 0x4d627
0x549cf36f      jvm!jio_printf + 0x9f
0x54a4dc30      jvm!JVM_GetThreadStateNames + 0x70080
0x54a4e4aa      jvm!JVM_GetThreadStateNames + 0x708fa
0x54a92ec6      jvm!_JVM_FindSignal@4 + 0x5b46
0x5a94c556      msvcr100!_endthreadex + 0x3a
0x5a94c600      msvcr100!_endthreadex + 0xe4
0x76968744      KERNEL32!BaseThreadInitThunk + 0x24
0x7780584d      ntdll!RtlGetAppContainerNamedObjectPath + 0xfd
0x7780581d      ntdll!RtlGetAppContainerNamedObjectPath + 0xcd
----------------- 4 -----------------
0x77811d6c      ntdll!ZwWaitForSingleObject + 0xc
0x76b0d0c2      KERNELBASE!WaitForSingleObject + 0x12
0x54a8fcd9      jvm!_JVM_FindSignal@4 + 0x2959
0x54a31c11      jvm!JVM_GetThreadStateNames + 0x54061
0x54a47744      jvm!JVM_GetThreadStateNames + 0x69b94
0x549d2155      jvm!_JVM_MonitorWait@16 + 0x95
0x0275d3d3      * java.lang.Object.wait(long) bci:0 (Interpreted frame)
0x02754854      * java.lang.ref.ReferenceQueue.remove(long) bci:59 line:143 (Interpreted frame)
0x027547b4      * java.lang.ref.ReferenceQueue.remove() bci:2 line:164 (Interpreted frame)
0x027547b4      * java.lang.ref.Finalizer$FinalizerThread.run() bci:36 line:209 (Interpreted frame)
0x02750697      <StubRoutines>
0x54a2af45      jvm!JVM_GetThreadStateNames + 0x4d395
0x54af13ae      jvm!_JVM_FindSignal@4 + 0x6402e
0x54a2afde      jvm!JVM_GetThreadStateNames + 0x4d42e
0x54a2b166      jvm!JVM_GetThreadStateNames + 0x4d5b6
0x54a2b1d7      jvm!JVM_GetThreadStateNames + 0x4d627
0x549cf36f      jvm!jio_printf + 0x9f
0x54a4dc30      jvm!JVM_GetThreadStateNames + 0x70080
0x54a4e4aa      jvm!JVM_GetThreadStateNames + 0x708fa
0x54a92ec6      jvm!_JVM_FindSignal@4 + 0x5b46
0x5a94c556      msvcr100!_endthreadex + 0x3a
0x5a94c600      msvcr100!_endthreadex + 0xe4
0x76968744      KERNEL32!BaseThreadInitThunk + 0x24
0x7780584d      ntdll!RtlGetAppContainerNamedObjectPath + 0xfd
0x7780581d      ntdll!RtlGetAppContainerNamedObjectPath + 0xcd
----------------- 5 -----------------
0x77811d6c      ntdll!ZwWaitForSingleObject + 0xc
0x76b0d0c2      KERNELBASE!WaitForSingleObject + 0x12
0x54a93519      jvm!_JVM_FindSignal@4 + 0x6199
0x54a935e7      jvm!_JVM_FindSignal@4 + 0x6267
0x54a4dc30      jvm!JVM_GetThreadStateNames + 0x70080
0x54a4e4aa      jvm!JVM_GetThreadStateNames + 0x708fa
0x54a92ec6      jvm!_JVM_FindSignal@4 + 0x5b46
0x5a94c556      msvcr100!_endthreadex + 0x3a
0x5a94c600      msvcr100!_endthreadex + 0xe4
0x76968744      KERNEL32!BaseThreadInitThunk + 0x24
0x7780584d      ntdll!RtlGetAppContainerNamedObjectPath + 0xfd
0x7780581d      ntdll!RtlGetAppContainerNamedObjectPath + 0xcd
----------------- 6 -----------------
0x77811d6c      ntdll!ZwWaitForSingleObject + 0xc
0x76b0d0c2      KERNELBASE!WaitForSingleObject + 0x12
0x54a8c5d2      jvm!JVM_GetThreadStateNames + 0xaea22
0x54a4dc30      jvm!JVM_GetThreadStateNames + 0x70080
0x54a4e4aa      jvm!JVM_GetThreadStateNames + 0x708fa
0x54a92ec6      jvm!_JVM_FindSignal@4 + 0x5b46
0x5a94c556      msvcr100!_endthreadex + 0x3a
0x5a94c600      msvcr100!_endthreadex + 0xe4
0x76968744      KERNEL32!BaseThreadInitThunk + 0x24
0x7780584d      ntdll!RtlGetAppContainerNamedObjectPath + 0xfd
0x7780581d      ntdll!RtlGetAppContainerNamedObjectPath + 0xcd
----------------- 7 -----------------
0x77811d6c      ntdll!ZwWaitForSingleObject + 0xc
0x76b0d0c2      KERNELBASE!WaitForSingleObject + 0x12
0x54a8fbcd      jvm!_JVM_FindSignal@4 + 0x284d
0x54a2cbdc      jvm!JVM_GetThreadStateNames + 0x4f02c
0x54a2cf5a      jvm!JVM_GetThreadStateNames + 0x4f3aa
0x54940b5b      jvm!_JVM_GetManagementExt@4 + 0x5565b
0x54a4dc30      jvm!JVM_GetThreadStateNames + 0x70080
0x54a4e4aa      jvm!JVM_GetThreadStateNames + 0x708fa
0x54a92ec6      jvm!_JVM_FindSignal@4 + 0x5b46
0x5a94c556      msvcr100!_endthreadex + 0x3a
0x5a94c600      msvcr100!_endthreadex + 0xe4
0x76968744      KERNEL32!BaseThreadInitThunk + 0x24
0x7780584d      ntdll!RtlGetAppContainerNamedObjectPath + 0xfd
0x7780581d      ntdll!RtlGetAppContainerNamedObjectPath + 0xcd
----------------- 8 -----------------
0x77811d6c      ntdll!ZwWaitForSingleObject + 0xc
0x76b0d0c2      KERNELBASE!WaitForSingleObject + 0x12
0x54a8fcd9      jvm!_JVM_FindSignal@4 + 0x2959
0x54a2cbd1      jvm!JVM_GetThreadStateNames + 0x4f021
0x54a2cf0c      jvm!JVM_GetThreadStateNames + 0x4f35c
0x54a3b9b1      jvm!JVM_GetThreadStateNames + 0x5de01
0x54a4dc30      jvm!JVM_GetThreadStateNames + 0x70080
0x54a4e4aa      jvm!JVM_GetThreadStateNames + 0x708fa
0x54a92ec6      jvm!_JVM_FindSignal@4 + 0x5b46
0x5a94c556      msvcr100!_endthreadex + 0x3a
0x5a94c600      msvcr100!_endthreadex + 0xe4
0x76968744      KERNEL32!BaseThreadInitThunk + 0x24
0x7780584d      ntdll!RtlGetAppContainerNamedObjectPath + 0xfd
0x7780581d      ntdll!RtlGetAppContainerNamedObjectPath + 0xcd
----------------- 9 -----------------
0x77811d6c      ntdll!ZwWaitForSingleObject + 0xc
0x76b0d0c2      KERNELBASE!WaitForSingleObject + 0x12
0x54a8fbcd      jvm!_JVM_FindSignal@4 + 0x284d
0x54a2cbdc      jvm!JVM_GetThreadStateNames + 0x4f02c
0x54a2cf0c      jvm!JVM_GetThreadStateNames + 0x4f35c
0x54a48c94      jvm!JVM_GetThreadStateNames + 0x6b0e4
0x54a48d37      jvm!JVM_GetThreadStateNames + 0x6b187
0x54a92ec6      jvm!_JVM_FindSignal@4 + 0x5b46
0x5a94c556      msvcr100!_endthreadex + 0x3a
0x5a94c600      msvcr100!_endthreadex + 0xe4
0x76968744      KERNEL32!BaseThreadInitThunk + 0x24
0x7780584d      ntdll!RtlGetAppContainerNamedObjectPath + 0xfd
0x7780581d      ntdll!RtlGetAppContainerNamedObjectPath + 0xcd
----------------- 10 -----------------
0x77811d6c      ntdll!ZwWaitForSingleObject + 0xc
0x76b0d0c2      KERNELBASE!WaitForSingleObject + 0x12
0x54a8fcd9      jvm!_JVM_FindSignal@4 + 0x2959
0x54a31c11      jvm!JVM_GetThreadStateNames + 0x54061
0x54a47744      jvm!JVM_GetThreadStateNames + 0x69b94
0x549d2155      jvm!_JVM_MonitorWait@16 + 0x95
0x0275d3d3      * java.lang.Object.wait(long) bci:0 (Interpreted frame)
0x02754854      * java.lang.Object.wait() bci:2 line:502 (Interpreted frame)
0x02754854      * sun.TimeThread.run() bci:13 line:17 (Interpreted frame)
0x02750697      <StubRoutines>
0x54a2af45      jvm!JVM_GetThreadStateNames + 0x4d395
0x54af13ae      jvm!_JVM_FindSignal@4 + 0x6402e
0x54a2afde      jvm!JVM_GetThreadStateNames + 0x4d42e
0x54a2b166      jvm!JVM_GetThreadStateNames + 0x4d5b6
0x54a2b1d7      jvm!JVM_GetThreadStateNames + 0x4d627
0x549cf36f      jvm!jio_printf + 0x9f
0x54a4dc30      jvm!JVM_GetThreadStateNames + 0x70080
0x54a4e4aa      jvm!JVM_GetThreadStateNames + 0x708fa
0x54a92ec6      jvm!_JVM_FindSignal@4 + 0x5b46
0x5a94c556      msvcr100!_endthreadex + 0x3a
0x5a94c600      msvcr100!_endthreadex + 0xe4
0x76968744      KERNEL32!BaseThreadInitThunk + 0x24
0x7780584d      ntdll!RtlGetAppContainerNamedObjectPath + 0xfd
0x7780581d      ntdll!RtlGetAppContainerNamedObjectPath + 0xcd
----------------- 11 -----------------
0x7781399c      ntdll!ZwWaitForWorkViaWorkerFactory + 0xc
0x76968744      KERNEL32!BaseThreadInitThunk + 0x24
0x7780584d      ntdll!RtlGetAppContainerNamedObjectPath + 0xfd
0x7780581d      ntdll!RtlGetAppContainerNamedObjectPath + 0xcd

四、线程与Monitor

jstack的使用

  • 进入区(Entrt Set):表示线程通过synchronized要求获取对象的锁。如果对象未被锁住,则迚入拥有者;否则则在进入区等待。一旦对象锁被其他线程释放,立即参与竞争。
  • 拥有者(The Owner):表示某一线程成功竞争到对象锁。
  • 等待区(Wait Set) :表示线程通过对象的wait方法,释放对象的锁,并在等待区等待被唤醒。

说明:

一个 Monitor在某个时刻,只能被一个线程拥有,该线程就是 “Active Thread”,而其它线程为“Waiting Thread”,分别在两个队列 “ Entry Set”和 “Wait Set”里面等候。在 “Entry Set”中等待的线程状态是 “Waiting for monitor entry”,而在“Wait Set”中等待的线程状态是 “in Object.wait()”。 被 synchronized保护起来的代码段称为临界区,当一个线程申请进入临界区时,它就进入了 “Entry Set”队列。

线程状态:

1、NEW:线程刚刚被创建,也就是已经new过了,但是还没有调用start()方法,jstack命令不会列出处于此状态的线程信息。

2、RUNNABLE:RUNNABLE这个名字很具有欺骗性,很容易让人误以为处于这个状态的线程正在运行;事实上,这个状态只是表示,线程是可运行的。一个单核CPU在同一时刻,只能运行一个线程。

3、BLOCKED:线程处于阻塞状态,正在等待一个监视器锁(monitor lock)。通常情况下,是因为本线程与其他线程公用了一个锁。其他在线程正在使用这个锁进入某个synchronized同步方法块或者方法,而本线程进入这个同步代码块也需要这个锁,最终导致本线程处于阻塞状态。

4、WAITING:等待状态,等待某个condition或monitor发生,调用以下方法可能会导致一个线程处于等待状态:

   ①wait() 不指定超时时间   

   ②join() 不指定超时时间

   ③park():阻塞线程

5、TIMED_WAITING:线程等待指定的时间,对于以下方法的调用,可能会导致线程处于这个状态:

   ①wait(long timeout) 指定超时时间

   ②join(long millis) 指定超时时间

   ③sleep(long millis) 指定超时时间

   ④parkNanos(long nanos) 

   ⑤parkUntil(long deadline) 

6、TERMINATED:线程终止。

上一篇:[JVM]线上CPU负载持续飙高的问题解决


下一篇:这些APP开发技巧可少花60万!