线程转储分析工具/方法

当Java应用程序挂起时,您甚至不知道导致此问题的用例并希望进行调查,我知道线程转储可能很有用。

但是我们怎样才能从线程转储中轻松地获取有用的数据来找出问题所在? 我一直在使用的服务器应用程序产生了非常长的线程转储,因为它是一个EJB体系结构,线程转储包含许多容器线程,我不知道应该看看(即线程不运行我的应用程序代码,但是JBoss的代码)。

昨天我尝试了线程转储分析工具。 该工具肯定比在文本编辑器中查看原始线程转储更好,因为您可以筛选出您不感兴趣的线程,查看线程列表,单击某个线程以查看其详细信息,比较线程转储以查找长时间运行的线程等。见下面的截图:

线程转储分析器

但是仍然有太多的数据需要分析 – 几乎有300个线程。 我不知道有什么标准可以用来过滤所有的JBoss线程,我不感兴趣。 我不确定是否应该只查看当前处于“可运行”状态的线程,或者“等待条件”和“Object.wait”中的线程也很重要。

你通常会遵循什么样的方法,以及一般使用的工具?

只有一组线程转储不会太有用,从而find根本原因。

诀窍是在每个间隔5秒的时间内采集4或5组线程转储。 所以最后你将有一个单独的日志文件,在应用服务器上有大约20到25秒的行动。

你想检查什么时候卡住的线程或长时间运行的事务发生时,所有的线程转储将显示一个特定的线程id是在你的java堆栈跟踪中的同一行。 简单地说,事务(比如在EJB或数据库中)横跨多个线程转储,因此需要更多的调查。

现在,当你通过武士 (我没有使用TDA自己)运行这些,它会突出显示这些红色,所以你可以快速点击它,并得到问题的线路。

在这里看到一个例子。 看看那个链接中的Samurai输出图像。 绿色的细胞很好。 红色和灰色细胞需要看。

从我自己的networking应用程序下面的武士例子显示在5 – 10秒的跨度螺纹'19'卡住序列

> 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线程转储分析器 ,这对Tomcat而不是Samurai非常有用

我知道这是一个老问题,但我只是写了一个工具,以帮助使长线程转储更具可读性。

Java线程转储分析工具

此工具将线程分组在一起,它们具有相同的堆栈跟踪,并允许您只显示处于特定状态(例如RUNNABLE或BLOCKED)的线程。

这使得在几十或几百个JBoss线程中find感兴趣的线程更快一些,这些线程花费大部分时间在代码中等待工作,因此都具有相同的堆栈跟踪。

我不确定是否应该只查看当前处于“可运行”状态的线程,或者“等待条件”和“Object.wait”中的线程也很重要。

后两者实际上诊断僵局时要查找东西,正如你似乎正在做的那样。 “Runnable”表示线程正在执行某些操作(或等待CPU)。 “阻塞”和“等待”是由什么造成的。

当然,一个应用程序容器将有大量的线程等待合法。 要过滤出有趣的情况,请查看堆栈跟踪。 如果是框架类(特别是称为“工作者”或“队列”),则可能是好的。 如果是应用程序代码,则应该更仔细地查看它。