jstack簡介


jstack:Java進程中線程的堆棧信息跟蹤工具

功能簡介

jstack常用來打印Java進程/core文件/遠程調試端口的Java線程堆棧跟蹤信息,包含當前虛擬機中所有線程正在執行的方法堆棧信息的集合。

主要用來定位線程出現長時間停頓的原因,如線程間死鎖、死循環、請求外部資源導致的長時間等待。

命令格式

1 jstack [ options ] pid                                      //Java進程
2 jstack [ options ] executable core                          //core文件
3 jstack [ options ] [ server-id@ ] remote-hostname-or-IP     //遠程調試端口

其中options選項可有

選項 作用
-F 當正常輸出的請求不被響應時,強制輸出線程堆棧
-l 除了堆棧外,顯示關於鎖的附加信息
-m 如果調用到本地方法的話,可以顯示C/C++的堆棧信息

 

 

 

 

其他說明

1、When the specified process is running on a 64-bit Java Virtual Machine, you might need to specify the -J-d64 option, for example: jstack -J-d64 -m pid.

2、In mixed mode stack trace, the -m option does not work with the remote debug server.

3、In Windows Systems where the dbgeng.dll file is not present, Debugging Tools For Windows must be installed so these tools work.

輸出格式

jstack的輸出是該進程下的所有線程的堆棧集合,下面是一個線程的堆棧快照信息:

 1 "pool-1-thread-3" #12 prio=5 os_prio=0 tid=0x00007fc99412f000 nid=0x9bc in Object.wait() [0x00007fc97c2f2000]
 2    java.lang.Thread.State: WAITING (on object monitor)
 3     at java.lang.Object.wait(Native Method)
 4     - waiting on <0x00000000d7017420> (a com.liang.java.thinkinginjava.concurency.waxomatic.Car)
 5     at java.lang.Object.wait(Object.java:502)
 6     at com.liang.java.thinkinginjava.concurency.waxomatic.Car.waitForBuffing(WaxOMatic.java:47)
 7     - locked <0x00000000d7017420> (a com.liang.java.thinkinginjava.concurency.waxomatic.Car)
 8     at com.liang.java.thinkinginjava.concurency.waxomatic.WaxOn.run(WaxOMatic.java:61)
 9     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
10     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
11     at java.lang.Thread.run(Thread.java:745)
12 
13    Locked ownable synchronizers:
14     - <0x00000000d729cdb0> (a java.util.concurrent.ThreadPoolExecutor$Worker)

其中 "pool-1-thread-3" 是線程名稱

 prio=5 是該線程JVM中的優先級

 os_prio=0 是該線程在OS中的優先級

 tid=0x00007fc99412f000 是JVM內的thread id (Java-level thread ID)

 nid=0x9bc 是Native thread ID,本地操作系統相關的線程id

This ID is highly platform dependent. It's the nid in jstack thread dumps.

  • On Windows, it's simply the OS-level thread ID within a process.

  • On Linux, it's the pid of the thread (which in turn is a light-weight process).

  • On Solaris, it's the thread as returned by thr_self().

  • On Mac OS X, it is said to be the native pthread_t value.

線程狀態

 在jstack輸出的第二行為線程的狀態,在JVM中線程狀態使用枚舉 java.lang.Thread.State 來表示,State的定義如下:

 1 /**
 2  * A thread can be in only one state at a given point in time.
 3  * These states are virtual machine states which do not reflect any operating system thread states.
 4  */
 5 public enum State {
 6     /**
 7      * A thread that has not yet started is in this state.
 8      */
 9     NEW,
10 
11     /**
12      * A thread executing in the Java virtual machine is in this state.
13      */
14     RUNNABLE,
15 
16     /**
17      * A thread that is blocked waiting for a monitor lock is in this state.
18      */
19     BLOCKED,
20 
21     /**
22      * A thread that is waiting indefinitely for another thread to perform a particular action is in this state.
23      */
24     WAITING,
25 
26     /**
27      * A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.
28      */
29     TIMED_WAITING,
30 
31     /**
32      * A thread that has exited is in this state.
33      */
34     TERMINATED;
35 }

這個狀態是指的JVM中的狀態,與任何操作系統的線程狀態都沒有任何關系。

其中RUNNABLE表示:線程在JVM中是可以執行的了,但是他可能還在等待着某些操作系統資源,如:cpu

其中BLOCKED表示:表示線程在等待或被notify后等待重新進入synchronized代碼塊/方法

其中WAITING表示:表示調用了Object.wait()/Thread.join()/LockSupport.park()方法,等待被另一個線程喚醒。例如一個線程調用了Object.wait(),在等待另一個線程調用Object.notify()/Object.notifyAll();一個線程調用了Thread.join(),在等待另一線程到達terinate狀態

其中TIMED_WAITING表示:表示線程調用了Object.sleep(long)/Object.wait(long)/Thread.join(long)/LockSupport.parkNanos()/LockSupport.parkUntil()等,等待一段時間后就會自動結束的方法;

也就是說BLOCKED在等待鎖,WAITING在等待被其他線程,TIMED_WAITING是帶鬧鍾的WAITING

下面獻上網上找到的一個高清狀態轉換圖:

樣例

java線程的獲得:使用jps -l,或者使用top命令查看使用cpu/memory最多的進程id,或者ps -aux | grep java

進程id的獲得:top -Hp pid,找到改線程下的最繁忙的進程id(十進制要轉換成16進制:printf "%x\n" tid)

jstack -l pid | grep tid

關於各種線程狀態下的例子,網上實在是太多了,一搜一大把! 

參考

https://gist.github.com/rednaxelafx/843622

https://segmentfault.com/a/1190000008506752


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM