【问题标题】:Thread Dump Analysis Tool / Method [closed]线程转储分析工具/方法[关闭]
【发布时间】:2020-10-07 07:06:47
【问题描述】:

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

但是我们如何才能轻松地从线程转储中获取有用的数据以找出问题所在呢?我一直在使用的服务器应用程序会产生非常长的线程转储,因为它是一个 EJB 架构,并且线程转储包含许多我不确定是否应该查看的容器线程(即没有运行我的应用程序代码的线程,而是 JBoss 的代码)。

昨天我尝试了Thread Dump Analyzer 工具。该工具绝对比在文本编辑器中查看原始线程转储要好,因为您可以过滤掉您不感兴趣的线程,查看线程列表,单击线程以查看其详细信息,比较线程转储以查找长时间运行的线程等。

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

您通常会采用哪些方法以及您通常会使用哪些工具?

【问题讨论】:

标签: java debugging deadlock thread-dump


【解决方案1】:

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

Java Thread Dump Analysis Tool

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

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

【讨论】:

  • 感谢伟大的工具。实际上它是第一个工具,它完全符合我的要求:) 感谢分享。
  • 这真的很有用。我最近在 tomcat TD 上使用了它,它很容易指出阻塞的线程。
  • 这个工具真的很有帮助。简单明了。 +1
【解决方案2】:

单独的一组线程转储不会太有助于找到根本原因。

诀窍是在每组之间以 5 秒的间隔进行 4 或 5 组线程转储。所以最后你会得到一个日志文件,它在应用服务器上有大约 20 - 25 秒的操作时间。

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

现在,当您通过Samurai(我自己没有使用过 TDA)运行这些内容时,它会以红色突出显示这些内容,以便您可以快速单击它并找到显示问题的行。

查看this here 的示例。查看该链接中的 Samurai 输出图像。绿色细胞很好。红色和灰色单元格需要查看。

下面我自己的网络应用程序中的 Samurai 示例显示了 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,相对于 Samurai,它对 Tomcat 非常有用

【讨论】:

【解决方案3】:

我不确定我是否应该看 当前处于的线程 仅“可运行”状态或“等待”状态 on condition”和“in Object.wait”是 也很重要。

后两者实际上是 在诊断死锁时要寻找的东西,就像您似乎正在做的那样。 “可运行”意味着线程现在正在做某事(或等待获取 CPU)。 “阻塞”和“等待”是死锁的组成部分。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-08
    • 2010-09-27
    • 2016-08-15
    • 2014-04-19
    • 2010-09-05
    • 1970-01-01
    相关资源
    最近更新 更多