天天看點

java jstack使用_jstack指令的使用

文章來源:https://blog.csdn.net/wufaliang003/article/details/80414267

jstack是java虛拟機自帶的一種堆棧跟蹤工具。

jstack用于生成java虛拟機目前時刻的線程快照。線程快照是目前java虛拟機内每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的原因,

如線程間死鎖、死循環、請求外部資源導緻的長時間等待等。 線程出現停頓的時候通過jstack來檢視各個線程的調用堆棧,就可以知道沒有響應的線程到底在背景做什麼事情,或者

等待什麼資源。 如果java程式崩潰生成core檔案,jstack工具可以用來獲得core檔案的java stack和native stack的資訊,進而可以輕松地知道java程式是如何崩潰和在程

序何處發生問題。另外,jstack工具還可以附屬到正在運作的java程式中,看到當時運作的java程式的java stack和native stack的資訊, 如果現在運作的java程式呈現hung

的狀态,jstack是非常有用的。

jstack指令:

Usage:

jstack [-l] (to connect to running process)

jstack-F [-m] [-l] (to connect to a hung process)

jstack [-m] [-l] (to connect to a core file)

jstack [-m] [-l] [[email protected]](to connect to a remote debug server)

Options:-F to force a thread dump. Use when jstack does not respond (process ishung)-m to print both java and native frames (mixed mode)-l longlisting. Prints additional information about locks-h or -help to print this help message

-F 當’jstack [-l] pid’沒有相應的時候強制列印棧資訊,如果直接jstack無響應時,用于強制jstack,一般情況不需要使用

-l 長清單. 列印關于鎖的附加資訊,例如屬于java.util.concurrent的ownable synchronizers清單,會使得JVM停頓得長久得多

(可能會差很多倍,比如普通的jstack可能幾毫秒和一次GC沒差別,加了-l 就是近一秒的時間),-l 建議不要用。一般情況不需要使用

-m 列印java和native c/c++ 架構的所有棧資訊.可以列印JVM的堆棧,顯示上Native的棧幀,一般應用排查不需要使用

執行指令:

jstack -m 12905

Attaching to process ID 12905, please wait...

Debugger attached successfully.

Server compiler detected.

JVM versionis 24.71-b01

Deadlock Detection:

No deadlocks found.----------------- 12908 -----------------

0x000000358d40b63c __pthread_cond_wait + 0xcc

0x00007fcad07875a5 Unsafe_Park + 0x125

0x00007fcacc4b17f8 * sun.misc.Unsafe.park(boolean, long) bci:0(Interpreted frame)0x00007fcacc4a5058 * java.util.concurrent.locks.LockSupport.park(java.lang.Object) bci:14 line:186(Interpreted frame)0x00007fcacc4a5058 * java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt() bci:1 line:834(Interpreted frame)0x00007fcacc4a5350 * java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(int) bci:72 line:994(Interpreted frame)0x00007fcacc4a5058 * java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(int) bci:24 line:1303 (Interpreted frame)

線程狀态

想要通過jstack指令來分析線程的情況的話,首先要知道線程都有哪些狀态,下面這些狀态是我們使用jstack指令檢視線程堆棧資訊時可能會看到的線程的幾種狀态:

NEW,未啟動的。不會出現在Dump中。

RUNNABLE,在虛拟機内執行的。

BLOCKED,受阻塞并等待螢幕鎖。

WATING,無限期等待另一個線程執行特定操作。

TIMED_WATING,有時限的等待另一個線程的特定操作。

TERMINATED,已退出的。

Monitor

在多線程的 JAVA程式中,實作線程之間的同步,就要說說 Monitor。 Monitor是 Java中用以實作線程之間的互斥與協作的主要手段,它可以看成是對象或者 Class的鎖。每一個對象都有,

也僅有一個 monitor。下 面這個圖,描述了線程和 Monitor之間關系,以 及線程的狀态轉換圖:

java jstack使用_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()”。

先看 “Entry Set”裡面的線程。我們稱被 synchronized保護起來的代碼段為臨界區。當一個線程申請進入臨界區時,它就進入了 “Entry Set”隊列。