【Java 虛擬機器筆記】jstack 堆疊跟蹤工具相關整理
文前說明
作為碼農中的一員,需要不斷的學習,我工作之餘將一些分析總結和學習筆記寫成部落格與大家一起交流,也希望採用這種方式記錄自己的學習之旅。
本文僅供學習交流使用,侵權必刪。
不用於商業目的,轉載請註明出處。
1. 堆疊跟蹤工具(Stack Trace for Java)
-
jstack 命令用於生成虛擬機器當前時刻的執行緒快照(一般稱為 threaddump 或者 javacore 檔案)。
- 執行緒快照就是當前虛擬機器內每一條執行緒正在執行的方法堆疊的集合,生成執行緒快照的主要目的是定位執行緒出現長時間停頓的原因,如執行緒間死鎖、死迴圈、請求外部資源導致的長時間等待等。
- 可以通過-J 方式,將虛擬機器引數傳遞給 jstack 呼叫的啟動程式。例如 -J-Xms48m。
- 如果給定程序是在 64 位虛擬機器上執行,那麼需要指定引數-J-d64 。
1.1 命令格式
- jstack [ option ] pid
- jstack [ option ] executable core
-
jstack [ option ] [server-id@]remote-hostname-or-IP
- options 是選項相互排斥。選項(如果使用)應緊跟在命令名之後。
- pid 是需要列印配置資訊的程序的 ID。這個程序必須是一個 Java 程序。為了獲得在機器上執行的 Java 程序的列表可以使用jps 命令。
- executable 是產生核心堆的 Java 可執行檔案。
- core 是需要列印配置資訊的核心檔案。
-
remote-hostname-or-IP 是遠端除錯伺服器的主機名或 IP 地址。
- 不指定的情況下執行 jstack,將在本地主機上查詢虛擬機器程序。
- server-id 如果在同一遠端主機上執行多個除錯伺服器,則為可選的唯一 ID。
選項 | 說明 |
---|---|
-F強制。 | 使用 jstack [-l] pid 無響應時可以強制執行。 |
-l | 長清單,列印有關鎖的其他資訊。http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/locks/AbstractOwnableSynchronizer.html 。 |
-m | 列印混合模式(Java 和 native C/C++)堆疊跟蹤。 |
-h | 列印幫助資訊。 |
-help | 列印幫助資訊。 |
1.2 執行樣例
- 列印有關鎖的其他資訊(瞭解Monitor 相關 和執行緒狀態 相關)。
[root@localhost ~]# sudo -u ovirt jstack -l 1638 2019-02-23 04:02:51 Full thread dump OpenJDK 64-Bit Server VM (24.161-b00 mixed mode): "process reaper" daemon prio=10 tid=0x00007fe2900cb800 nid=0x30b8 waiting on condition [0x00007fe26c74d000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for<0x00000000cd765128> (a java.util.concurrent.SynchronousQueue$TransferStack) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226) at java.util.concurrent.SynchronousQueue$TransferStack.awaitFulfill(SynchronousQueue.java:460) at java.util.concurrent.SynchronousQueue$TransferStack.transfer(SynchronousQueue.java:359) at java.util.concurrent.SynchronousQueue.poll(SynchronousQueue.java:942) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1075) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1137) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:622) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - None "Attach Listener" daemon prio=10 tid=0x00007fe2900cb000 nid=0x2cb7 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "ajp-/127.0.0.1:8702-11" daemon prio=10 tid=0x00007fe278308800 nid=0x7e1 in Object.wait() [0x00007fe26bea2000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:503) at org.apache.tomcat.util.net.JIoEndpoint$Worker.await(JIoEndpoint.java:881) - locked <0x00000000d0102e68> (a org.apache.tomcat.util.net.JIoEndpoint$Worker) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:907) at java.lang.Thread.run(Thread.java:748) Locked ownable synchronizers: - None "ajp-/127.0.0.1:8702-10" daemon prio=10 tid=0x00007fe2783cf000 nid=0x7da runnable [0x00007fe26bfa3000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.read(SocketInputStream.java:153) at java.net.SocketInputStream.read(SocketInputStream.java:122) at org.apache.coyote.ajp.AjpProcessor.read(AjpProcessor.java:1124) at org.apache.coyote.ajp.AjpProcessor.readMessage(AjpProcessor.java:1206) at org.apache.coyote.ajp.AjpProcessor.process(AjpProcessor.java:438) at org.apache.coyote.ajp.AjpProtocol$AjpConnectionHandler.process(AjpProtocol.java:420) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:926) at java.lang.Thread.run(Thread.java:748)
1.3 輸出格式
資訊 | 說明 |
---|---|
prio | 執行緒的優先順序 |
tid | 執行緒 ID |
nid | 作業系統對映的執行緒 ID,(例如:nid=0x75a) |
0x00007fcd86af2000 | 表示執行緒棧的起始地址。 |
0x00000000c709e5c0 | 鎖的物件的 ID |
發現死鎖現象
Found one Java-level deadlock: ============================= "Thread-1": waiting to lock monitor 0x0003f334 (object 0x22c19f18, a java.lang.Object), which is held by "Thread-0" "Thread-0": waiting to lock monitor 0x0003f314 (object 0x22c19f20, a java.lang.Object), which is held by "Thread-1"