Thread dumps
(线程转储)能帮助咱们判断 CPU 峰值、死锁、内存异常、应用反应迟钝、响应时间变长和其余系统问题。一些在线的分析工具好比 http://fastthread.io/ 也能帮助咱们分析和定位问题,可是这些工具都要求有一个 dump 文件。所以在这篇文章当中,我总结了7中抓取 Java Thread Dumps 文件的方式。java
jstack
是一个抓取 thread dump
文件的有效的命令行工具,它位于 JDK 目录里的 bin 文件夹下(JDK_HOME\bin),如下是抓取 dump 文件的命令:tomcat
jstack -l <pid> > <file-path>
说明:安全
pid: Java 应用的进程 id ,也就是须要抓取 dump 文件的应用进程 id。app
file-path: 保存 dump 文件的路径。工具
示例:性能
jstack -l 37320 > /opt/tmp/threadDump.txt
上面的例子演示了用 jstack 生成 dump 文件到 /opt/tmp/threadDump.txt
目录下。ui
从 Java5 开始,jstack 被包含进了 jdk 当中,若是你使用老版本的 jdk,要考虑使用其余方式。this
处于安全方面的考虑,有一部分生产环境的机器只包含 JRE 环境,所以就不能使用 jstack 工具了,在这种状况下,咱们可使用 kill -3
的方式:spa
kill -3 <pid>
说明:操作系统
示例:
kill -3 37320
当使用 kill -3
生成 dump 文件时,dump 文件会被输出到标准错误流。假如你的应用运行在 tomcat 上,dump 内容将被发送到<TOMCAT_HOME>/logs/catalina.out
文件里。
Java VisualVM 是一个能够提供 JVM 信息的图形界面工具。它位于 JDK_HOME\bin\jvisualvm.exe
文件里。从 JDK6 Update7 开始,它被包含进 JDK 里。
运行 jvisualvm,在左侧面板中(以下图所示),列出了运行的 JVM 信息,这个工具能够从本地或者远程运行的 JVM 里抓取 dump 文件。
点击上图的进程名称对应的 Thread Dump
按钮,将会生成 dump 文件,以下图所示:
Java Mission Control (JMC) 是一个能从本地或生产环境中收集和分析数据的工具,从 Oracle JDK 7 Update 40 开始,它被包含进 JDK 里,它能够从 JVM 里生成 dump 文件。JMC 位于 JDK_HOME\bin\jmc.exe
文件里:
运行该工具以后,你能够看到运行在本地的 Java 进程,它也能够链接到远程机器。双击你想要生成 dump 文件的 Java 进程,点击Flight Recorder
,你会看到如下的对话框:
在 Thread Dump
下拉框,你能够选择生成 dump 文件的时间间隔。在上面的例子里,每隔60秒将会生成一个 dump 文件。选择完成以后启动 Flight recorder ,能够在 Threads 面板看到 dump 文件的内容:
这种方式仅仅在 Windows 操做系统上有效:
在控制台窗口上选中命令行
在命令行窗口上按 “Ctrl + Break” 命令
而后会生成 dump 文件,dump 文件的内容会被打印在命令行窗口上。
注意1: 有几款笔记本(好比 Lenovo T 系列)已经取消了 “Break” 键,在这种状况下你不得不用谷歌搜索与 Break 键功能相似的键,我发现 “Function key + B” 键与 Break 键的功能相同,所以我用 “Ctrl + Fn + B” 键来生成 dump 文件。
注意2: 用上述方式有一个缺点就是 dump 文件的内容会被打印到控制台上,没有 dump 文件的话,咱们很难用分析工具好比http://fasthread.io来分析 dump 文件。所以你可使用如下命令将 dump 文件的内容输出到文本文件当中,好比你的应用程序名字叫 SampleThreadProgram ,那么一般使用的命令以下:
java -classpath . SampleThreadProgram
将 dump 文件的内容输出到文本文件的命令以下:
java -classpath . SampleThreadProgram > C:\workspace\threadDump.txt 2>&1
当你按下 “Ctrl + Break” 键以后,dump 文件会被保存到 C:\workspace\threadDump.txt 里。
从 JDK 1.5 开始,ThreadMXBean 被引入。这是 JVM 的管理接口,使用这个接口你仅须要少许的代码就能生成 dump 文件,如下是使用 ThreadMXBean 生成 dump 文件的主要实现:
public void dumpThreadDump() { ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean(); for (ThreadInfo ti : threadMxBean.dumpAllThreads(true, true)) { System.out.print(ti.toString()); } }
一些应用性能监控工具提供了生成 dump 文件的功能,若是你使用 App Dynamics 监控你的应用,如下就是生成 dump 文件的步骤:
打开建立动做窗口,在建立动做窗口中选择 Diagnostics->Take a thread dump;
输入动做名称、抓取 dump 文件的数量、抓取 dump 文件的时间间隔(毫秒);
若是你想在抓取 dump 动做开始以前执行一些操做,那么你能够选中 Require approval executing before this Action
这个复选框,而后输入我的或小组的 email 地址;
点击 OK.
尽管我在前面列出了7种抓取 dump 文件的方式,但恕我直言,jstack
和 kill -3
是最好的选择,缘由以下:
a. 简单,容易实现;
b. 通用:在大多数状况下,无论操做系统类型、Java 厂商、JVM 版本等等。
编译自:https://dzone.com/articles/how-to-take-thread-dumps-7-options