1、介绍
jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式:
jstack [-l] pid
如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。
2、命令格式
jstack [ option ] pidjstack [ option ] executable core
jstack [ option ] [server-id@]remote-hostname-or-IP
3、常用参数说明
1)、options:
executable Java executable from which the core dump was produced.
(可能是产生core dump的java可执行程序)
core 将被打印信息的core dump文件
remote-hostname-or-IP 远程debug服务的主机名或ip
server-id 唯一id,假如一台主机上多个远程debug服务
2)、基本参数:
-F当’jstack [-l] pid’没有相应的时候强制打印栈信息
-l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
-m打印java和native c/c++框架的所有栈信息.
-h | -help打印帮助信息
pid 需要被打印配置信息的java进程id,可以用jps查询.
4、jstack分析线程死锁
线程死锁的代码如下。
-
- public class ThreadDeadLockDemo {
- public static void main(String[] args) {
- final Object obj_1 = new Object(), obj_2 = new Object();
- Thread first = new Thread("first"){
- @Override
- public void run() {
- synchronized (obj_1) {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {}
- synchronized (obj_2) {
- System.out.println("first thread done.");
- }
- }
- }
- };
- Thread second = new Thread("second"){
- @Override
- public void run() {
- synchronized (obj_2) {
- try {
- Thread.sleep(3000);
- } catch (InterruptedException e) {}
- synchronized (obj_1) {
- System.out.println("seconde thread done.");
- }
- }
- }
- };
- first.start();
- second.start();
- }
- }
"Attach Listener" daemon prio=10 tid=0x00007f87d0001000 nid=0x7c1 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"DestroyJavaVM" prio=10 tid=0x00007f87fc005800 nid=0x793 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"second" prio=10 tid=0x00007f87fc0aa800 nid=0x7a1 waiting for monitor entry [0x00007f87fa5c1000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ThreadDeadLockDemo$2.run(ThreadDeadLockDemo.java:10)
- waiting to lock <0x00000007d7036b40> (a java.lang.Object)
- locked <0x00000007d7036b50> (a java.lang.Object)
"first" prio=10 tid=0x00007f87fc0a8800 nid=0x7a0 waiting for monitor entry [0x00007f87fa6c2000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ThreadDeadLockDemo$1.run(ThreadDeadLockDemo.java:10)
- waiting to lock <0x00000007d7036b50> (a java.lang.Object)
- locked <0x00000007d7036b40> (a java.lang.Object)
"Low Memory Detector" daemon prio=10 tid=0x00007f87fc08f800 nid=0x79e runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=10 tid=0x00007f87fc08d800 nid=0x79d waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=10 tid=0x00007f87fc08a800 nid=0x79c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=10 tid=0x00007f87fc088800 nid=0x79b runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=10 tid=0x00007f87fc06c000 nid=0x79a in Object.wait() [0x00007f87facc8000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007d7001300> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0x00000007d7001300> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:171)
"Reference Handler" daemon prio=10 tid=0x00007f87fc06a000 nid=0x799 in Object.wait() [0x00007f87fadc9000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007d70011d8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x00000007d70011d8> (a java.lang.ref.Reference$Lock)
"VM Thread" prio=10 tid=0x00007f87fc063800 nid=0x798 runnable
"GC task thread#0 (ParallelGC)" prio=10 tid=0x00007f87fc019000 nid=0x794 runnable
"GC task thread#1 (ParallelGC)" prio=10 tid=0x00007f87fc01a800 nid=0x795 runnable
"GC task thread#2 (ParallelGC)" prio=10 tid=0x00007f87fc01c800 nid=0x796 runnable
"GC task thread#3 (ParallelGC)" prio=10 tid=0x00007f87fc01e800 nid=0x797 runnable
"VM Periodic Task Thread" prio=10 tid=0x00007f87fc09a800 nid=0x79f waiting on condition
JNI global references: 882
Found one Java-level deadlock:
=============================
"second":
waiting to lock monitor 0x00007f87dc005f10 (object 0x00000007d7036b40, a java.lang.Object),
which is held by "first"
"first":
waiting to lock monitor 0x00007f87dc004b60 (object 0x00000007d7036b50, a java.lang.Object),
which is held by "second"
Java stack information for the threads listed above:
===================================================
"second":
at ThreadDeadLockDemo$2.run(ThreadDeadLockDemo.java:10)
- waiting to lock <0x00000007d7036b40> (a java.lang.Object)
- locked <0x00000007d7036b50> (a java.lang.Object)
"first":
at ThreadDeadLockDemo$1.run(ThreadDeadLockDemo.java:10)
- waiting to lock <0x00000007d7036b50> (a java.lang.Object)
- locked <0x00000007d7036b40> (a java.lang.Object)
Found 1 deadlock.
"Attach Listener" daemon prio=10 tid=0x00007f87d0001000 nid=0x7c1 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"DestroyJavaVM" prio=10 tid=0x00007f87fc005800 nid=0x793 waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"second" prio=10 tid=0x00007f87fc0aa800 nid=0x7a1 waiting for monitor entry [0x00007f87fa5c1000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ThreadDeadLockDemo$2.run(ThreadDeadLockDemo.java:10)
- waiting to lock <0x00000007d7036b40> (a java.lang.Object)
- locked <0x00000007d7036b50> (a java.lang.Object)
"first" prio=10 tid=0x00007f87fc0a8800 nid=0x7a0 waiting for monitor entry [0x00007f87fa6c2000]
java.lang.Thread.State: BLOCKED (on object monitor)
at ThreadDeadLockDemo$1.run(ThreadDeadLockDemo.java:10)
- waiting to lock <0x00000007d7036b50> (a java.lang.Object)
- locked <0x00000007d7036b40> (a java.lang.Object)
"Low Memory Detector" daemon prio=10 tid=0x00007f87fc08f800 nid=0x79e runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread1" daemon prio=10 tid=0x00007f87fc08d800 nid=0x79d waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"C2 CompilerThread0" daemon prio=10 tid=0x00007f87fc08a800 nid=0x79c waiting on condition [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Signal Dispatcher" daemon prio=10 tid=0x00007f87fc088800 nid=0x79b runnable [0x0000000000000000]
java.lang.Thread.State: RUNNABLE
"Finalizer" daemon prio=10 tid=0x00007f87fc06c000 nid=0x79a in Object.wait() [0x00007f87facc8000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007d7001300> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)
- locked <0x00000007d7001300> (a java.lang.ref.ReferenceQueue$Lock)
at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)
at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:171)
"Reference Handler" daemon prio=10 tid=0x00007f87fc06a000 nid=0x799 in Object.wait() [0x00007f87fadc9000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000007d70011d8> (a java.lang.ref.Reference$Lock)
at java.lang.Object.wait(Object.java:485)
at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)
- locked <0x00000007d70011d8> (a java.lang.ref.Reference$Lock)
"VM Thread" prio=10 tid=0x00007f87fc063800 nid=0x798 runnable
"GC task thread#0 (ParallelGC)" prio=10 tid=0x00007f87fc019000 nid=0x794 runnable
"GC task thread#1 (ParallelGC)" prio=10 tid=0x00007f87fc01a800 nid=0x795 runnable
"GC task thread#2 (ParallelGC)" prio=10 tid=0x00007f87fc01c800 nid=0x796 runnable
"GC task thread#3 (ParallelGC)" prio=10 tid=0x00007f87fc01e800 nid=0x797 runnable
"VM Periodic Task Thread" prio=10 tid=0x00007f87fc09a800 nid=0x79f waiting on condition
JNI global references: 882
Found one Java-level deadlock:
=============================
"second":
waiting to lock monitor 0x00007f87dc005f10 (object 0x00000007d7036b40, a java.lang.Object),
which is held by "first"
"first":
waiting to lock monitor 0x00007f87dc004b60 (object 0x00000007d7036b50, a java.lang.Object),
which is held by "second"
Java stack information for the threads listed above:
===================================================
"second":
at ThreadDeadLockDemo$2.run(ThreadDeadLockDemo.java:10)
- waiting to lock <0x00000007d7036b40> (a java.lang.Object)
- locked <0x00000007d7036b50> (a java.lang.Object)
"first":
at ThreadDeadLockDemo$1.run(ThreadDeadLockDemo.java:10)
- waiting to lock <0x00000007d7036b50> (a java.lang.Object)
- locked <0x00000007d7036b40> (a java.lang.Object)
Found 1 deadlock.