2010-07-01 82 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