如何使用 jstack 分析執行緒狀態

佔小狼發表於2016-12-05

背景

記得前段時間,同事說他們測試環境的伺服器cpu使用率一直處於100%,本地又沒有什麼介面呼叫,為什麼會這樣?cpu使用率居高不下,自然是有某些執行緒一直佔用著cpu資源,那又如何檢視佔用cpu較高的執行緒?

如何使用 jstack 分析執行緒狀態

當然一個正常的程式設計師不會寫出上述程式碼,這裡只是為了讓一個執行緒佔用較高的cpu資源。

top命令

在linux環境下,可以通過top命令檢視各個程式的cpu使用情況,預設按cpu使用率排序

如何使用 jstack 分析執行緒狀態

1、上圖中可以看出pid為23344的java程式佔用了較多的cpu資源;
2、通過top -Hp 23344可以檢視該程式下各個執行緒的cpu使用情況;

如何使用 jstack 分析執行緒狀態

上圖中可以看出pid為25077的執行緒佔了較多的cpu資源,利用jstack命令可以繼續檢視該執行緒當前的堆疊狀態。

jstack命令

通過top命令定位到cpu佔用率較高的執行緒之後,繼續使用jstack pid命令檢視當前java程式的堆疊狀態

如何使用 jstack 分析執行緒狀態

jstack命令生成的thread dump資訊包含了JVM中所有存活的執行緒,為了分析指定執行緒,必須找出對應執行緒的呼叫棧,應該如何找?

在top命令中,已經獲取到了佔用cpu資源較高的執行緒pid,將該pid轉成16進位制的值,在thread dump中每個執行緒都有一個nid,找到對應的nid即可;隔段時間再執行一次stack命令獲取thread dump,區分兩份dump是否有差別,在nid=0x246c的執行緒呼叫棧中,發現該執行緒一直在執行JstackCase類第33行的calculate方法,得到這個資訊,就可以檢查對應的程式碼是否有問題。

通過thread dump分析執行緒狀態

除了上述的分析,大多數情況下會基於thead dump分析當前各個執行緒的執行情況,如是否存在死鎖、是否存在一個執行緒長時間持有鎖不放等等。

在dump中,執行緒一般存在如下幾種狀態:
1、RUNNABLE,執行緒處於執行中
2、BLOCKED,執行緒被阻塞
3、WAITING,執行緒正在等待

例項1:多執行緒競爭synchronized鎖

如何使用 jstack 分析執行緒狀態

很明顯:執行緒1獲取到鎖,處於RUNNABLE狀態,執行緒2處於BLOCK狀態
1、locked 說明執行緒1對地址為0x000000076bf62208物件進行了加鎖;
2、waiting to lock 說明執行緒2在等待地址為0x000000076bf62208物件上的鎖;
3、waiting for monitor entry [0x000000001e21f000]說明執行緒1是通過synchronized關鍵字進入了監視器的臨界區,並處於”Entry Set”佇列,等待monitor;

例項2:通過wait掛起執行緒

dump結果

如何使用 jstack 分析執行緒狀態

 執行緒1和2都處於WAITING狀態

1、執行緒1和2都是先locked ,再waiting on ,之所以先鎖再等同一個物件,是因為wait方法需要先通過synchronized獲得該地址物件的monitor;
2、waiting on 說明執行緒執行了wait方法之後,釋放了monitor,進入到”Wait Set”佇列,等待其它執行緒執行地址為0x000000076bf62500物件的notify方法,並喚醒自己;

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

如何使用 jstack 分析執行緒狀態

相關文章