2010-07-01 84 views
58

當Java應用程序掛起時,您甚至不知道導致此問題並想要調查的用例,我知道線程轉儲可能很有用。線程轉儲分析工具/方法

但是,我們如何從線程轉儲中輕鬆導出有用的數據以找到問題所在?我一直在使用的服務器應用程序產生了非常長的線程轉儲,因爲它是一個EJB體系結構,並且線程轉儲包含許多容器線程,我不知道應該查看哪些線程轉儲(即未運行我的應用程序代碼的線程,但是JBoss的代碼)。

昨天我試了Thread Dump Analyzer工具。該工具肯定比在文本編輯器中查看原始線程轉儲更好,因爲您可以過濾掉您不感興趣的線程,查看線程列表,單擊某個線程查看其詳細信息,比較線程轉儲以查找長時間運行的線程等見下圖:

Thread Dump Analyzer

但還是有太多的數據來分析 - 近300個線程。我不知道有什麼標準可以用來過濾掉所有的JBoss線程,我不感興趣。我不確定是否應該只查看當前處於「可運行」狀態的線程,或者「等待條件」和「Object.wait」中的線程也很重要。

您通常會遵循什麼方法以及您通常會使用的工具?

+0

另請參閱https://www.ibm.com/developerworks/community/groups/service/html/communityview?communityUuid=2245aa39-fa5c-4475-b891-14c205f7333c – oluies 2014-11-04 08:17:24

+4

我寫了這個,它分析線程轉儲,沒有安裝必要:http://spotify.github.io/threaddump-analyzer/ – 2015-09-22 13:22:59

+0

@JohanWalles漂亮的工具! – ycomp 2017-01-27 13:04:01

回答

26

單獨一套線程轉儲不會對幫助解決問題的根本原因有所幫助。

訣竅是每5秒鐘間隔取4或5組線程轉儲。所以最後你會有一個日誌文件,在應用服務器上有大約20到25秒的動作。

你想要檢查的是當一個卡住的線程或長時間運行的事務發生時,所有的線程轉儲都會顯示某個線程id在你的java堆棧跟蹤中的同一行。簡而言之,事務(比如在EJB或數據庫中)橫跨多個線程轉儲,因此需要更多的調查。

現在,當您通過Samurai(我本人沒有使用過TDA)運行這些代碼時,它會以紅色突出顯示這些顏色,以便您快速點擊並顯示問題。

查看this here的示例。查看該鏈接中的Samurai輸出圖像。綠色的細胞很好。紅色和灰色細胞需要觀察。從下我自己的web應用程序

武士的例子顯示了Thread'19' 跨越5跨度卡住序列 - 10秒

>  Thread dump 2/3 "[ACTIVE] ExecuteThread: '19' for queue: 
> 'weblogic.kernel.Default 
> (self-tuning)'" daemon prio=7 
> tid=07b06000 nid=108 lwp_id=222813 
> waiting for monitor entry 
> [2aa40000..2aa40b30]  
> java.lang.Thread.State: BLOCKED (on 
> object monitor)  at 
> com.bea.p13n.util.lease.JDBCLeaseManager.renewLease(JDBCLeaseManager.java:393) 
> - waiting to lock <735e9f88> (a com.bea.p13n.util.lease.JDBCLeaseManager) 
> at 
> com.bea.p13n.util.lease.Lease$LeaseTimer.timerExpired(Lease.java:229) 

...

> Thread dump 3/3 "[ACTIVE] 
> ExecuteThread: '19' for queue: 
> 'weblogic.kernel.Default 
> (self-tuning)'" daemon prio=7 
> tid=07b06000 nid=108 lwp_id=222813 
> waiting for monitor entry 
> [2aa40000..2aa40b30]  
> java.lang.Thread.State: BLOCKED (on 
> object monitor)  at 
> com.bea.p13n.util.lease.JDBCLeaseManager.renewLease(JDBCLeaseManager.java:393) 
> - waiting to lock <735e9f88> (a com.bea.p13n.util.lease.JDBCLeaseManager) 
> at 
> com.bea.p13n.util.lease.Lease$LeaseTimer.timerExpired(Lease.java:229) 

更新

我最近使用了Java Thread Dump Analyzer提到的in this answer,它對於Tomcat而言非常有用,而非Sa murai

6

我不知道我是否應該看 線程當前在 「可運行」僅或者狀態「等待條件 」和「的Object.wait」是 也很重要。

後兩者實際上是的事情,尋找診斷死鎖時,你似乎做的事情。 「Runnable」表示線程正在執行某項操作(或等待CPU)。 「阻塞」和「等待」是由什麼造成的。

當然,一個應用程序容器將有大量線程等待合法。要過濾出有趣的情況,請查看堆棧跟蹤。如果是框架類(特別是稱爲「工作者」或「隊列」的框架),則可能是好的。如果是應用程序代碼,則應該更仔細地查看它。

27

我知道這是一個老問題,但我只是寫了一個工具來幫助使長線程轉儲更具可讀性。

Java Thread Dump Analysis Tool

該工具組中的線程一起具有相同堆棧跟蹤並允許只顯示線程其在特定狀態(例如RUNNABLE或阻止)。

這使得在幾十或幾百個JBoss線程中查找感興趣的線程會更快一些,這些線程的大部分時間都花在代碼中等待工作的地方,因此它們都具有相同的堆棧跟蹤。

+3

感謝您的偉大工具。其實這是第一個工具,這正是我想要的:)感謝分享它。 – 2012-11-12 17:51:30

+0

這真的很有用。我最近在tomcat TD上使用了它,它非常容易地指出了Blocked線程。 – JoseK 2014-06-20 08:14:00

+0

這個工具真的很有用。簡單而重要。 +1 – 2015-06-17 07:39:52