Java 线程转储分析工具/方法

Java 线程转储分析工具/方法,java,debugging,deadlock,thread-dump,Java,Debugging,Deadlock,Thread Dump,当Java应用程序挂起时,您甚至不知道导致这种情况的用例,并且希望进行调查,我知道线程转储是有用的 但是,我们如何能够轻松地从线程转储中获得有用的数据,从而找到问题所在?我一直在使用的服务器应用程序会产生很长的线程转储,因为它是一个EJB体系结构,线程转储包含许多我不确定应该查看的容器线程(即,不是运行我的应用程序代码,而是运行JBoss代码的线程) 昨天我试过这个工具。该工具肯定比在文本编辑器中查看原始线程转储要好,因为您可以筛选出不感兴趣的线程,查看线程列表,单击线程查看其详细信息,比较线程

当Java应用程序挂起时,您甚至不知道导致这种情况的用例,并且希望进行调查,我知道线程转储是有用的

但是,我们如何能够轻松地从线程转储中获得有用的数据,从而找到问题所在?我一直在使用的服务器应用程序会产生很长的线程转储,因为它是一个EJB体系结构,线程转储包含许多我不确定应该查看的容器线程(即,不是运行我的应用程序代码,而是运行JBoss代码的线程)

昨天我试过这个工具。该工具肯定比在文本编辑器中查看原始线程转储要好,因为您可以筛选出不感兴趣的线程,查看线程列表,单击线程查看其详细信息,比较线程转储以查找长时间运行的线程,等等

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

您通常会采用什么方法以及通常会使用的工具

我不确定我是否应该看 当前正在运行的线程 仅“可运行”状态或“正在等待” 条件“on”和“in Object.wait”是 同样重要

在诊断死锁时,后面两个事实上是需要查找的,就像您正在做的那样。“Runnable”表示线程正在执行某些操作(或等待获取CPU)。“阻塞”和“等待”是死锁的组成部分


当然,应用程序容器将有大量线程合法地等待。要过滤出感兴趣的案例,请查看堆栈跟踪。如果是框架类(尤其是那些称为“Worker”或“Queue”的类),那么它可能没问题。如果它是应用程序代码,您应该更仔细地查看它。

单靠一组线程转储无法找到根本原因

诀窍是以5秒的间隔进行4或5组线程转储。因此,在最后,您将拥有一个日志文件,该文件在应用服务器上的操作时间大约为20-25秒

您要检查的是,当发生卡住的线程或长时间运行的事务时,所有线程转储将显示某个线程id在java堆栈跟踪中的同一行。简单地说,事务(比如EJB或数据库中的事务)跨越多个线程转储,因此需要更多的研究

现在,当您运行这些(我自己没有使用TDA)时,它将以红色突出显示这些,以便您可以快速单击它并进入显示问题的行

参见一个示例。请看该链接中的武士输出图像。绿色细胞很好。红细胞和灰细胞需要观察

下面我自己的web应用程序中的一个武士示例显示了线程'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)
>线程转储2/3“[ACTIVE]ExecuteThread:'19'用于队列:
>'weblogic.kernel.Default
>(自调整)“”守护进程优先级=7
>tid=07b06000 nid=108 lwp_id=222813
>正在等待监视器条目
>[2aa40000..2aa40b30]
>java.lang.Thread.State:已阻止(打开
>对象监视器)在
>com.bea.p13n.util.lease.JDBCLeaseManager.renewLease(JDBCLeaseManager.java:393)
>-等待锁定(com.bea.p13n.util.lease.jdbcleasemager)
>在
>com.bea.p13n.util.lease.lease$LeaseTimer.timerExpired(lease.java:229)

>线程转储3/3”[活动]
>队列的ExecuteThread:“19”:
>'weblogic.kernel.Default
>(自调整)“”守护进程优先级=7
>tid=07b06000 nid=108 lwp_id=222813
>正在等待监视器条目
>[2aa40000..2aa40b30]
>java.lang.Thread.State:已阻止(打开
>对象监视器)在
>com.bea.p13n.util.lease.JDBCLeaseManager.renewLease(JDBCLeaseManager.java:393)
>-等待锁定(com.bea.p13n.util.lease.jdbcleasemager)
>在
>com.bea.p13n.util.lease.lease$LeaseTimer.timerExpired(lease.java:229)
更新


我最近使用了提到的,它对Tomcat非常有用,而不是Samurai

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

此工具将具有相同堆栈跟踪的线程分组在一起,并允许您仅显示处于特定状态(例如可运行或已阻止)的线程


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

感谢这一伟大的工具。事实上,这是第一个工具,它正是我想要的:)谢谢分享。这真的很有用。我最近在TomcatTD上使用了这个工具,它很容易指出阻塞的线程。这个工具非常有用。简明扼要+1请看我写的,它分析线程转储,无需安装:@JohanWalles nice tool!武士工具可以在这里找到
> 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)