java-jvm-jstack

jstack用于打印出给定的java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项"-J-d64",Windows的jstack使用方式只支持以下的这种方式:
jstack [-l] pid
jstack [ option ] [server-id@]remote-hostname-or-IP


基本参数:
-F当’jstack [-l] pid’没有相应的时候强制打印栈信息
-l长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.
-m打印java和native c/c++框架的所有栈信息.

注意:-F参数 一般不要加,它是取当前挂起的线程信息,很多东西拿不到

注意:此命令会列出系统存在的死锁

Java代码 
  1. sudo jstack -F  27409 > data.txt  
  2. sudo jstack -J-d64 -F  27409  



输出:

Java代码 
  1. Deadlock Detection:  
  2.   
  3. No deadlocks found.  
  4.   
  5. Thread 2768: (state = BLOCKED)  
  6.  - sun.misc.Unsafe.park(booleanlong@bci=0 (Compiled frame; information may be imprecise)  
  7.  - java.util.concurrent.locks.LockSupport.parkNanos(java.lang.Object, long@bci=20, line=226 (Compiled frame)  
  8.  - java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(long@bci=68, line=2082 (Compiled frame)  
  9.  - java.util.concurrent.ArrayBlockingQueue.poll(long, java.util.concurrent.TimeUnit) @bci=49, line=389 (Compiled frame)  
  10.  - java.util.concurrent.ThreadPoolExecutor.getTask() @bci=141, line=1068 (Compiled frame)  
  11.  - java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) @bci=26, line=1130 (Compiled f  
  12. rame)  
  13.  - java.util.concurrent.ThreadPoolExecutor$Worker.run() @bci=5, line=615 (Interpreted frame)  
  14.  - java.lang.Thread.run() @bci=11, line=744 (Interpreted frame)  
  15.   
  16.   
  17. Thread 31971: (state = BLOCKED)  
  18.  - sun.misc.Unsafe.park(booleanlong@bci=0 (Compiled frame; information may be imprecise)  
  19.  - java.util.concurrent.locks.LockSupport.parkNanos(java.lang.Object, long@bci=20, line=226 (Compiled frame)  



有锁的例子-------->
代码:

Java代码 
  1. class T1 extends Thread {  
  2.     private Object lockA;  
  3.     private Object lockB;  
  4.       
  5.     public T1(Object lockA,Object lockB){  
  6.         this.lockA = lockA;  
  7.         this.lockB = lockB;  
  8.     }  
  9.       
  10.     @Override  
  11.     public void run() {  
  12.         System.out.println("T1 runing begin");  
  13.         synchronized (lockA) {  
  14.             try {  
  15.                 Thread.sleep(1000);  
  16.             } catch (InterruptedException e) {  
  17.             }  
  18.               
  19.             synchronized (lockB) {  
  20.                 System.out.println("T1 runing over");  
  21.             }  
  22.         }  
  23.     }  
  24. }  
  25.   
  26.   
  27.   
  28.   
  29. class T2 extends Thread {  
  30.     private Object lockA;  
  31.     private Object lockB;  
  32.       
  33.     public T2(Object lockA,Object lockB){  
  34.         this.lockA = lockA;  
  35.         this.lockB = lockB;  
  36.     }  
  37.       
  38.     @Override  
  39.     public void run() {  
  40.         System.out.println("T2 runing begin");  
  41.         synchronized (lockB) {  
  42.             try {  
  43.                 Thread.sleep(1000);  
  44.             } catch (InterruptedException e) {  
  45.             }  
  46.               
  47.             synchronized (lockA) {  
  48.                 System.out.println("T2 runing over");  
  49.             }  
  50.         }  
  51.     }  
  52. }  
  53.   
  54. /** 
  55.  * @author xinchun.wang 
  56.  */  
  57. public class LockTest {  
  58.   
  59.     public static void main(String[] args) {  
  60.         Object lockA = new Object();  
  61.         Object lockB = new Object();  
  62.         T1 t1 = new T1(lockA,lockB);  
  63.           
  64.           
  65.         T2 t2 = new T2(lockA,lockB);  
  66.         t1.start();  
  67.         t2.start();  
  68.   
  69.     }  
  70. }  



输出:
T1 runing begin
T2 runing begin

Java代码 
  1. C:\Windows\System32>jstack  22144  
  2. 2016-08-09 20:00:10  
  3. Full thread dump Java HotSpot(TM) 64-Bit Server VM (20.14-b01 mixed mode):  
  4.   
  5. "DestroyJavaVM" prio=6 tid=0x00000000008ac000 nid=0xd134 waiting on condition [0x0000000000000000]  
  6.    java.lang.Thread.State: RUNNABLE  
  7.   
  8. "Thread-1" prio=6 tid=0x00000000068c7000 nid=0x6d0c waiting for monitor entry [0x000000000733f000]  
  9.    java.lang.Thread.State: BLOCKED (on object monitor)  
  10.         at com.springapp.mvc.com.springapp.mvc.T2.run(LockTest.java:50)  
  11.         - waiting to lock <0x00000007d5fa25e8> (a java.lang.Object)  
  12.         - locked <0x00000007d5fa25f8> (a java.lang.Object)  
  13.   
  14. "Thread-0" prio=6 tid=0x00000000068c4800 nid=0xbf28 waiting for monitor entry [0x000000000723f000]  
  15.    java.lang.Thread.State: BLOCKED (on object monitor)  
  16.         at com.springapp.mvc.com.springapp.mvc.T1.run(LockTest.java:22)  
  17.         - waiting to lock <0x00000007d5fa25f8> (a java.lang.Object)  
  18.         - locked <0x00000007d5fa25e8> (a java.lang.Object)  
  19.   
  20. "Low Memory Detector" daemon prio=6 tid=0x00000000068b0800 nid=0xd270 runnable [0x0000000000000000]  
  21.    java.lang.Thread.State: RUNNABLE  
  22.   
  23. "C2 CompilerThread1" daemon prio=10 tid=0x00000000068a3800 nid=0xbe48 waiting on condition [0x0000000000000000]  
  24.    java.lang.Thread.State: RUNNABLE  
  25.   
  26. "C2 CompilerThread0" daemon prio=10 tid=0x0000000006859800 nid=0xd2e4 waiting on condition [0x0000000000000000]  
  27.    java.lang.Thread.State: RUNNABLE  
  28.   
  29. "Attach Listener" daemon prio=10 tid=0x0000000006858800 nid=0xb5fc waiting on condition [0x0000000000000000]  
  30.    java.lang.Thread.State: RUNNABLE  
  31.   
  32. "Signal Dispatcher" daemon prio=10 tid=0x0000000006853800 nid=0xc62c runnable [0x0000000000000000]  
  33.    java.lang.Thread.State: RUNNABLE  
  34.   
  35. "Finalizer" daemon prio=8 tid=0x0000000006845800 nid=0xcd4c in Object.wait() [0x0000000006b3f000]  
  36.    java.lang.Thread.State: WAITING (on object monitor)  
  37.         at java.lang.Object.wait(Native Method)  
  38.         - waiting on <0x00000007d5f61300> (a java.lang.ref.ReferenceQueue$Lock)  
  39.         at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)  
  40.         - locked <0x00000007d5f61300> (a java.lang.ref.ReferenceQueue$Lock)  
  41.         at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)  
  42.         at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)  
  43.   
  44. "Reference Handler" daemon prio=10 tid=0x0000000000828000 nid=0x92d0 in Object.wait() [0x000000000683f000]  
  45.    java.lang.Thread.State: WAITING (on object monitor)  
  46.         at java.lang.Object.wait(Native Method)  
  47.         - waiting on <0x00000007d5f611d8> (a java.lang.ref.Reference$Lock)  
  48.         at java.lang.Object.wait(Object.java:485)  
  49.         at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)  
  50.         - locked <0x00000007d5f611d8> (a java.lang.ref.Reference$Lock)  
  51.   
  52. "VM Thread" prio=10 tid=0x0000000000822000 nid=0x7e60 runnable  
  53.   
  54. "GC task thread#0 (ParallelGC)" prio=6 tid=0x0000000000778000 nid=0xce94 runnable  
  55.   
  56. "GC task thread#1 (ParallelGC)" prio=6 tid=0x0000000000779800 nid=0xc574 runnable  
  57.   
  58. "GC task thread#2 (ParallelGC)" prio=6 tid=0x000000000077c000 nid=0x7f18 runnable  
  59.   
  60. "GC task thread#3 (ParallelGC)" prio=6 tid=0x000000000077d800 nid=0x7f1c runnable  
  61.   
  62. "VM Periodic Task Thread" prio=10 tid=0x00000000068b9800 nid=0xc3dc waiting on condition  
  63.   
  64. JNI global references: 882  
  65.   
  66.   
  67. Found one Java-level deadlock:  
  68. =============================  
  69. "Thread-1":  
  70.   waiting to lock monitor 0x0000000006842b30 (object 0x00000007d5fa25e8, a java.lang.Object),  
  71.   which is held by "Thread-0"  
  72. "Thread-0":  
  73.   waiting to lock monitor 0x00000000068453e0 (object 0x00000007d5fa25f8, a java.lang.Object),  
  74.   which is held by "Thread-1"  
  75.   
  76. Java stack information for the threads listed above:  
  77. ===================================================  
  78. "Thread-1":  
  79.         at com.springapp.mvc.com.springapp.mvc.T2.run(LockTest.java:50)  
  80.         - waiting to lock <0x00000007d5fa25e8> (a java.lang.Object)  
  81.         - locked <0x00000007d5fa25f8> (a java.lang.Object)  
  82. "Thread-0":  
  83.         at com.springapp.mvc.com.springapp.mvc.T1.run(LockTest.java:22)  
  84.         - waiting to lock <0x00000007d5fa25f8> (a java.lang.Object)  
  85.         - locked <0x00000007d5fa25e8> (a java.lang.Object)  
  86.   
  87. Found 1 deadlock.  



线程状态的分析:
Runnable:该状态表示线程具备所有运行条件,在运行队列中准备操作系统的调度,或者正在运行。

Wait on condition :
该状态出现在线程等待某个条件的发生。具体是什么原因,可以结合 stacktrace来分析。最常见的情况是线程在等待网络的读写,比如当网络数据没有准备好读时,线程处于这种等待状态,而一旦有数据准备好读之后,线程会重新激活,读取并处理数据。在 Java引入 NewIO之前,对于每个网络连接,都有一个对应的线程来处理网络的读写操作,即使没有可读写的数据,线程仍然阻塞在读写操作上,这样有可能造成资源浪费,而且给操作系统的线程调度也带来压力。在 NewIO里采用了新的机制,编写的服务器程序的性能和可扩展性都得到提高。
        如果发现有大量的线程都在处在 Wait on condition,从线程 stack看, 正等待网络读写,这可能是一个网络瓶颈的征兆。因为网络阻塞导致线程无法执行。一种情况是网络非常忙,几 乎消耗了所有的带宽,仍然有大量数据等待网络读 写;另一种情况也可能是网络空闲,但由于路由等问题,导致包无法正常的到达。所以要结合系统的一些性能观察工具来综合分析,比如 netstat统计单位时间的发送包的数目,如果很明显超过了所在网络带宽的限制 ; 观察 cpu的利用率,如果系统态的 CPU时间,相对于用户态的 CPU时间比例较高;如果程序运行在 Solaris 10平台上,可以用 dtrace工具看系统调用的情况,如果观察到 read/write的系统调用的次数或者运行时间遥遥领先;这些都指向由于网络带宽所限导致的网络瓶颈。另外一种出现 Wait on condition的常见情况是该线程在 sleep,等待 sleep的时间到了时候,将被唤醒。

BLOCKED: 线程sleep 就会进入这个
锁的分析:
Found 1 deadlock.

其中:
Thread-1 持有0x00000007d5fa25f8 锁,希望获取0x00000007d5fa25e8
Thread-2 持有0x00000007d5fa25e8锁,希望获取0x00000007d5fa25f8


"Thread-0":
  waiting to lock monitor 0x00000000068453e0 (object 0x00000007d5fa25f8, a java.lang.Object),
  which is held by "Thread-1"
也会提醒:Thread-0 需要获取的0x00000007d5fa25f8 是由 Thread-1 持有。

其他:

  TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程,用

printf "%x\n" 21742

    得到21742的十六进制值为54ee,下面会用到。    

    OK,下一步终于轮到jstack上场了,它用来输出进程21711的堆栈信息,然后根据线程ID的十六进制值grep

猜你喜欢

转载自wangxinchun.iteye.com/blog/2315713