1. 程式人生 > 程式設計 >JDK14效能管理工具之jstack使用介紹

JDK14效能管理工具之jstack使用介紹

在之前的文章中,我們介紹了JDK14中jstat工具的使用,本文我們再深入探討一下jstack工具的使用。

jstack工具主要用來列印java堆疊資訊,主要是java的class名字,方法名,位元組碼索引,行數等資訊。

jstack的命令格式

Usage:
  jstack [-l][-e] <pid>
    (to connect to running process)

Options:
  -l long listing. Prints additional information about locks
  -e extended listing. Prints additional information about threads
  -? -h --help -help to print this help message

jstack的引數比較簡單,l可以包含鎖的資訊,e包含了額外的資訊。

jstack的使用

我們舉個例子:

jstack -l -e 53528

輸出結果如下:

2020-05-09 21:46:51
Full thread dump Java HotSpot(TM) 64-Bit Server VM (14.0.1+7 mixed mode,sharing):
Threads class SMR info:
_java_thread_list=0x00007fda0660eb00,length=14,elements={
0x00007fda04811000,0x00007fda05845800,0x00007fda05012000,0x00007fda05847800,
0x00007fda05843800,0x00007fda05854800,0x00007fda0481f000,0x00007fda0481f800,

0x00007fda04018800,0x00007fda041ff800,0x00007fda05a28800,0x00007fda05b1a800,
0x00007fda05b1d800,0x00007fda042be000
}
"Reference Handler" #2 daemon prio=10 os_prio=31 cpu=0.67ms elapsed=66335.21s allocated=0B defined_classes=0 tid=0x00007fda04811000 nid=0x4603 waiting on condition [0x000070000afe1000]
java.lang.Thread.State: RUNNABLE
at java.lang.ref.Reference.waitForReferencePendingList([email protected]/Native Method)
at java.lang.ref.Reference.processPendingReferences([email protected]/Reference.java:241)
at java.lang.ref.Reference$ReferenceHandler.run([email protected]/Reference.java:213)
Locked ownable synchronizers:
- None
...
"VM Thread" os_prio=31 cpu=1433.78ms elapsed=66335.22s tid=0x00007fda0506b000 nid=0x4803 runnable
"GC Thread#0" os_prio=31 cpu=18.63ms elapsed=66335.23s tid=0x00007fda0502a800 nid=0x3203 runnable
"GC Thread#1" os_prio=31 cpu=19.64ms elapsed=66334.06s tid=0x00007fda050e5800 nid=0x9d03 runnable
"GC Thread#2" os_prio=31 cpu=17.72ms elapsed=66334.06s tid=0x00007fda05015000 nid=0x6203 runnable
"GC Thread#3" os_prio=31 cpu=14.57ms elapsed=66332.78s tid=0x00007fda05138800 nid=0x6503 runnable
"G1 Main Marker" os_prio=31 cpu=0.25ms elapsed=66335.23s tid=0x00007fda05031000 nid=0x3303 runnable
"G1 Conc#0" os_prio=31 cpu=14.85ms elapsed=66335.23s tid=0x00007fda05031800 nid=0x4b03 runnable
"G1 Refine#0" os_prio=31 cpu=3.25ms elapsed=66335.23s tid=0x00007fda0583a800 nid=0x4a03 runnable
"G1 Young RemSet Sampling" os_prio=31 cpu=5929.79ms elapsed=66335.23s tid=0x00007fda0505a800 nid=0x3503 runnable
"VM Periodic Task Thread" os_prio=31 cpu=21862.12ms elapsed=66335.13s tid=0x00007fda0505b000 nid=0xa103 waiting on condition
JNI global refs: 43,weak refs: 45

輸出的結果我們可以分為下面幾個部分:

JVM虛擬機器資訊

第一部分是JVM虛擬機器的資訊

2020-05-09 21:46:51
Full thread dump Java HotSpot(TM) 64-Bit Server VM (14.0.1+7 mixed mode,sharing):

上面顯示了虛擬機器的thread dump時間和虛擬機器的版本等資訊。

Threads class SMR info

第二部分是JVM中非JVM(非VM和非GC的執行緒)的內部執行緒資訊。

Threads class SMR info:
_java_thread_list=0x00007fda0660eb00,0x00007fda042be000
}

這些elements是和後面執行緒的tid相匹配的。表示的是本地執行緒物件的地址,注意這些不是執行緒的ID。

大家可能注意到了裡面寫的是SMR, SMR全稱是Safe Memory Reclamation。

什麼是SMR呢?簡單點講就是安全的記憶體分配,一般這個問題會出現在非自動GC的程式語言中如C++。在這些語言中,需要自己來為物件分配記憶體和銷燬物件,這樣就可能導致在多執行緒的環境中,一個地址可能被分配給了多個物件,從而出現了記憶體分配的不安全。

執行緒資訊

第三部分就是執行緒的具體資訊了:

"Reference Handler" #2 daemon prio=10 os_prio=31 cpu=0.67ms elapsed=66335.21s allocated=0B defined_classes=0 tid=0x00007fda04811000 nid=0x4603 waiting on condition [0x000070000afe1000]
  java.lang.Thread.State: RUNNABLE
  at java.lang.ref.Reference.waitForReferencePendingList(java.base@14.0.1/Native Method)
  at java.lang.ref.Reference.processPendingReferences([email protected]/Reference.java:241)
  at java.lang.ref.Reference$ReferenceHandler.run([email protected]/Reference.java:213)

  Locked ownable synchronizers:
  - None

按照欄位的順序,我們可以把執行緒資訊分為下面幾個部分:

  • 執行緒名字:例如Reference Handler
  • 執行緒的ID:例如#2
  • 是否守護執行緒:例如daemon,daemon threads是低優先順序的thread,它的作用是為User Thread提供服務。 因為daemon threads的低優先順序,並且僅為user thread提供服務,所以當所有的user thread都結束之後,JVM會自動退出,不管是否還有daemon threads在執行中。
  • 優先順序:例如prio=10
  • OS執行緒的優先順序:例如os_prio=31
  • cpu時間:執行緒獲得CPU的時間,例如cpu=0.67ms
  • elapsed:執行緒啟動後經過的wall clock time
  • allocated:本執行緒分配的分配的bytes數
  • defined_classes:本執行緒定義的class個數

注意'allocated=' 和 ‘defined_classes=' 必須要開啟 -XX:+PrintExtendedThreadInfo才會輸出資料。

  • Address:java執行緒的地址,例如:tid=0x00007fda04811000
  • OS執行緒ID:例如nid=0x4603
  • 執行緒狀態:例如waiting on condition
  • 最新的Java堆疊指標:最新的java堆疊指標SP,例如:[0x000070000afe1000]

接下來就是執行緒的堆疊資訊:

java.lang.Thread.State: RUNNABLE
  at java.lang.ref.Reference.waitForReferencePendingList(java.base@14.0.1/Native Method)
  at java.lang.ref.Reference.processPendingReferences([email protected]/Reference.java:241)
  at java.lang.ref.Reference$ReferenceHandler.run([email protected]/Reference.java:213)

上面的例子是執行緒的堆疊資訊,並且列出來了執行緒的狀態。

Locked Ownable Synchronizer

接下來的部分是該執行緒擁有的,可用的用於同步的排它鎖物件。

Ownable Synchronizer是一個同步器,這個同步器的同步屬性是通過使用AbstractOwnableSynchronizer或者它的子類來實現的。

例如ReentrantLock和ReentrantReadWriteLock中的write-lock(注意不是read-lock,因為需要排它性)就是兩個例子。

JVM Threads

接下來是JVM的執行緒資訊,因為這個執行緒是JVM內部的,所以沒有執行緒ID:

"VM Thread" os_prio=31 cpu=1433.78ms elapsed=66335.22s tid=0x00007fda0506b000 nid=0x4803 runnable

"GC Thread#0" os_prio=31 cpu=18.63ms elapsed=66335.23s tid=0x00007fda0502a800 nid=0x3203 runnable

"GC Thread#1" os_prio=31 cpu=19.64ms elapsed=66334.06s tid=0x00007fda050e5800 nid=0x9d03 runnable

"GC Thread#2" os_prio=31 cpu=17.72ms elapsed=66334.06s tid=0x00007fda05015000 nid=0x6203 runnable

"GC Thread#3" os_prio=31 cpu=14.57ms elapsed=66332.78s tid=0x00007fda05138800 nid=0x6503 runnable

"G1 Main Marker" os_prio=31 cpu=0.25ms elapsed=66335.23s tid=0x00007fda05031000 nid=0x3303 runnable

"G1 Conc#0" os_prio=31 cpu=14.85ms elapsed=66335.23s tid=0x00007fda05031800 nid=0x4b03 runnable

"G1 Refine#0" os_prio=31 cpu=3.25ms elapsed=66335.23s tid=0x00007fda0583a800 nid=0x4a03 runnable

"G1 Young RemSet Sampling" os_prio=31 cpu=5929.79ms elapsed=66335.23s tid=0x00007fda0505a800 nid=0x3503 runnable
"VM Periodic Task Thread" os_prio=31 cpu=21862.12ms elapsed=66335.13s tid=0x00007fda0505b000 nid=0xa103 waiting on condition

JNI References

最後一部分是JNI(Java Native Interface)引用的資訊,注意這些引用可能會導致記憶體洩露,因為這些native的引用並不會被自動垃圾回收。

JNI global refs: 43,weak refs: 45

jstack是分析執行緒的非常強大的工具,希望大家能夠使用起來。

總結

到此這篇關於JDK14效能管理工具之jstack使用介紹的文章就介紹到這了,更多相關JDK14效能管理工具jstack使用內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!