如何获取线程转储文件?- 8 大选项

线程转储是 CPU 占用激增、死锁、响应时间缓慢、内存问题、应用程序无响应及其他系统问题诊断过程中的重要工件。目前市面上有许多不错的在线线程转储分析工具(如:http://fastthread.io/),可帮助您分析和发现问题。但在使用这些工具时,您需要正确提供合适的线程转储文件,以作为其输入。因此,本文中将为您介绍 8 种不同的线程转储文件捕获选项。

1. jstack

jstack 是一款能够有效捕获线程转储文件的命令行工具。jstack 工具已随 JDK_HOME 的 bin 文件夹一同提供。如果您想对线程转储文件进行捕获,则需发出以下命令:

jstack -l  <pid> > <file-path>

其中:

pid – 应用程序的进程 ID(需要捕获转储文件的)

file-path – 转储文件将被写入的路径。

示例:

jstack -l 37320 > /opt/tmp/threadDump.txt

如上所示,进程的线程转储信息将被存入 /opt/tmp/threadDump.txt 文件中。

jstack 工具目前已随 Java 5 及更高版本的选项提供。如果您正在使用旧版本的 Jave,可考虑使用后文中的其它选项

2. Kill -3

大型企业出于安全考虑仅会在生产环境机器上安装 JRE。鉴于 jstack 与其他的一些工具仅是 JDK 的一部分,此时您将无法使用 jstack 工具。那么,这种情形中可考虑使用 kill -3。

kill -3 <pid>

其中:

pid – 应用程序的进程 ID(需要捕获转储文件的)

示例:

使用 kill -3 选项时,线程转储信息将被发送至标准错误信息流。如果您在 tomcat 中运行应用程序,那么线程转储信息将被输出至 <TOMCAT_HOME>/logs/catalina.out 文件中。

注意:据我所知,大部分 *nix 类型的操作系统(Unix、Linux、HP-UX 操作系统)均支持此选项。但对于其他操作系统我并不确定其是否可用。

3. JVisualVM

Java VisualVM 是一个具有图形化用户界面的工具,可提供有关应用程序在指定 Java 虚拟机(JVM)上运行时的详细信息。其位置在:JDK_HOME/bin/jvisualvm.exe,为 JDK 6 update 7.s 及更高版本 Sun JDK 分发版的组成部分

启动 jvisualvm。您可在左侧面板中看到机器上运行的所有 Java 应用程序。您需要从中选择自己的应用程序(下方插图中红线圈出的部分)。此工具还能从远程主机上所运行的 Java 进程中捕获线程转储文件。

Fig: Java Visual VM

图:Java Visual VM

现在前往“Threads”标签页。如下图所示,点击“Thread Dump”按钮。此时将生成线程转储文件。

Image title

图:“Threads”标签页中突出显示的“Thread Dump”按钮

4. JMC

Java Mission Control(JMC)是一种本地运行或部署于生产环境中的 Java 应用程序收集和数据分析工具。该工具自 Oracle JDK 7 Update 40 起就已打包在 JDK 中了。其同时还提供了从 JVM 中获取线程转储文件的选项。JMC 工具置于 JDK_HOME/bin/jmc.exe

启动工具后,您将看到所有运行于本地主机上的 Java 进程。注意:JMC 还可与远程主机上运行的 Java 进程进行连接。现在点击左侧面板中,于需要获取线程转储文件的 Java 进程下方列出的“Flight Recorder”选项。此时您将看到“Start Flight Recording”向导。如下图所示。

Image title

图:展示有“Thread Dump”捕获选项的 Flight Recorder 向导。

在“Thread Dump”字段中,您可选择捕获线程转储文件的间隔。在上面的示例中将每 60 秒捕获一次线程转储文件。完成选择后即可开始 Flight Recorder。完成记录后,您将在“Threads”面板中看到线程转储文件。如下图所示。

Image title

图:展示有已捕获“Thread Dump”的 JMC。

5. Windows(Ctrl + Break)

此选项仅在 Windows 操作系统中可用。

  • 选择您已启用应用程序的命令行控制台窗口。
  • 在窗口中发出“Ctrl + Break”命令。

此时将生成线程转储文件。线程转储文件将被输出至控制台窗口自身中。

备注 1:在多款笔记本中(比如我的联想 T 系列),“Break”键其实已经被移除了。此时您需要搜索一下“Break”的等效按键。就我的情况而言,事实证明“Break”的等效按键为“功能键 + B”。所以我会使用“Ctrl + Fn + B”组合键来生成线程转储文件。

备注 2:这种方法的一个缺点是,线程转储文件会被输出在 Windows 控制台自身中。您可能无法得到文件格式的线程转储文件,此时就很难使用线程转储文件分析工具(如:http://fastthread.io)来对其进行分析。因此,当您在从命令行中启动应用程序时,记得将输出重定向至一个文本文件。假设您所启动的应用程序为“SampleThreadProgram”,那么就输入以下命令:

java -classpath .SampleThreadProgram

然后以下面的方式来启动 SampleThreadProgram

java -classpath .SampleThreadProgram > C:workspacethreadDump.txt 2>&1

这样在发出“Ctrl + Break”命令时,线程转储文件就会被发送至 C:workspacethreadDump.txt 文件中。

6. ThreadMXBean

自 JDK 1.5 以来,ThreadMXBean 就已被引入。这是 Java 虚拟机线程系统的管理接口。您可使用这一接口来生成线程转储文件。只需编写几行代码即可以编程方式生成线程转储文件。下方是实现 ThreadMXBean 的框架。其将在应用程序中生成转储文件。

public void  dumpThreadDump() {
    ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
    for (ThreadInfo ti : threadMxBean.dumpAllThreads(true, true)) {
        System.out.print(ti.toString());
    }
}

7. APM 工具 – App Dynamics

部分应用程序性能监测工具也会提供生成线程转储文件的选项。如果您使用 App Dynamics(APM 工具)来监控应用程序,则可使用以下方式来捕获线程转储文件:

1. 创建一个操作并在创建操作窗口中选择 Diagnostics->Take a thread dump
2.输入操作名称,需要获取的样本数量,以及线程转储文件间的间隔(毫秒)。
3.如果您想在线程转储文件操作启动前获得批准,可勾选“在此操作前要求批准”复选框,并输入有权限批准该操作的个人或群组的邮件地址。请查看“需要批准的操作”以了解更多信息。
4.点击 OK

Image title

图:App Dynamics 线程转出文件捕获向导

8. JCMD

JCMD 工具已随附 Oracle Java 7 提供。其在对 JVM 应用程序进行故障排除时十分实用。该工具具有识别 java 进程 ID、获取堆内存转储文件、获取线程转储文件、获取垃圾回收统计数据等功能。

您可通过下方的 JCMD 命令来生成线程转储文件:

jcmd <pid> Thread.print > <file-path>

其中:

pid – 应用程序的进程 ID(需要捕获转储文件的)

file-path – 转储文件将被写入的路径。

示例:

jcmd 37320 Thread.print > /opt/tmp/threadDump.txt

如上所示,进程的线程转储信息将被存入 /opt/tmp/threadDump.txt 文件中。

结论

虽然这里我们列出了 8 种不同的选项,但实话实说,1.“jstack”、2.“kill -3”以及 8.“JCMD”是最佳选择。因为这三种方式:

a.十分简单(直观且易于实现)

b.通用(可在操作系统、Java 供应商、JVM 版本等方面存在不同的大部分情形中工作)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

Blog at WordPress.com.

Up ↑

%d bloggers like this: