Ivo*_*ssi 63 java debugging deadlock thread-dump
当Java应用程序挂起时,您甚至不知道导致这种情况的用例并想要调查,我理解线程转储可能很有用.
但是,我们如何从线程转储中轻松地获取有用的数据以找出问题所在?我一直在使用的服务器应用程序产生很长的线程转储,因为它是一个EJB体系结构,并且线程转储包含许多容器线程,我不确定我应该关注它们(即没有运行我的应用程序代码的线程) ,但JBoss的代码).
昨天我尝试了Thread Dump Analyzer工具.该工具肯定比在文本编辑器中查看原始线程转储更好,因为您可以过滤掉您不感兴趣的线程,查看线程列表,单击线程以查看其详细信息,比较线程转储以查找长时间运行的线程等.见下面的截图:

但仍有太多数据需要分析 - 近300个线程.我不知道有什么标准可以用来过滤掉所有我不感兴趣的JBoss线程.我不确定我是否应该查看当前处于"可运行"状态的线程,或者"等待条件"和"在Object.wait"中的线程也很重要.
您通常会遵循的方法和一般使用的工具是什么?
Jos*_*seK 29
单独一组线程转储对于找到根本原因不会太有帮助.
诀窍是在每个之间以5秒的间隔采取4或5组线程转储.因此,最后您将拥有一个日志文件,该文件在应用服务器上的操作时间大约为20-25秒.
你想要检查的是当一个卡住的线程或长时间运行的事务发生时,所有的线程转储都会显示某个线程id在你的java堆栈跟踪中的同一行.简单来说,事务(比如在EJB或数据库中)跨越多个线程转储,因此需要更多调查.
现在当你通过Samurai运行这些(我自己没有使用TDA)时,它会以红色突出显示这些颜色,这样你就可以快速点击它并找到显示问题的线条.
在这里查看此示例.查看该链接中的Samurai输出图像.绿色细胞很好.红色和灰色细胞需要看.
下面我自己的网络应用程序中的Samurai示例显示了在5到10秒的时间内Thread'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)
Run Code Online (Sandbox Code Playgroud)
...
> 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)
Run Code Online (Sandbox Code Playgroud)
更新
我最近使用了本答案中提到的Java Thread Dump Analyzer,它对Tomcat非常有用,而不是Samurai
mch*_*chr 29
我知道这是一个老问题,但我刚写了一个工具来帮助使长线程转储更具可读性.
此工具将具有相同堆栈跟踪的线程组合在一起,并允许您仅显示特定状态的线程(例如RUNNABLE或BLOCKED).
这使得在数十或数百个JBoss线程中找到有趣的线程变得更快一些,这些线程花费大部分时间在代码中的相同位置等待工作,因此所有线程都具有相同的堆栈跟踪.
我不确定我是否应该查看当前处于"可运行"状态的线程,或者"等待条件"和"在Object.wait"中的线程也很重要.
后两者实际上是在诊断死锁时要查找的内容,正如您似乎正在做的那样."Runnable"表示线程正在做某事(或等待获取CPU)."封锁"和"等待"是造成僵局的原因.
当然,应用程序容器将有足够的线程合法地等待.要过滤掉有趣的案例,请查看堆栈跟踪.如果是框架类(尤其是那些名为"Worker"或"Queue"的框架类),那可能就行了.如果是应用程序代码,您应该更仔细地查看它.