Java中抓取 Thread Dumps 的方式汇总
thread dumps(线程转储)能帮助我们判断 cpu 峰值、死锁、内存异常、应用反应迟钝、响应时间变长和其他系统问题。一些在线的分析工具比如 也能帮助我们分析和定位问题,但是这些工具都要求有一个 dump 文件。因此在这篇文章当中,我总结了7中抓取 java thread dumps 文件的方式。
1. jstack
jstack 是一个抓取 thread dump 文件的有效的命令行工具,它位于 jdk 目录里的 bin 文件夹下(jdk_home\bin),以下是抓取 dump 文件的命令:
jstack -l <pid> > <file-path>
说明:
pid: java 应用的进程 id ,也就是需要抓取 dump 文件的应用进程 id。
file-path: 保存 dump 文件的路径。
示例:
jstack -l 37320 > /opt/tmp/threaddump.txt
上面的例子演示了用 jstack 生成 dump 文件到 /opt/tmp/threaddump.txt 目录下。
从 java5 开始,jstack 被包含进了 jdk 当中,如果你使用老版本的 jdk,要考虑使用其他方式。
2. kill -3
处于安全方面的考虑,有一部分生产环境的机器只包含 jre 环境,因此就不能使用 jstack 工具了,在这种情况下,我们可以使用 kill -3 的方式:
kill -3 <pid>
说明:
pid: java 应用的进程 id ,也就是需要抓取 dump 文件的应用进程 id 。
示例:
kill -3 37320
当使用 kill -3 生成 dump 文件时,dump 文件会被输出到标准错误流。假如你的应用运行在 tomcat 上,dump 内容将被发送到<tomcat_home>/logs/catalina.out 文件里。
3. jvisualvm
java visualvm 是一个可以提供 jvm 信息的图形界面工具。它位于 jdk_home\bin\jvisualvm.exe 文件里。从 jdk6 update7 开始,它被包含进 jdk 里。
运行 jvisualvm,在左侧面板中(如下图所示),列出了运行的 jvm 信息,这个工具可以从本地或者远程运行的 jvm 里抓取 dump 文件。
点击上图的进程名称对应的 thread dump 按钮,将会生成 dump 文件,如下图所示:
4. jmc
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 文件的内容:
5. windows (ctrl + break)
这种方式仅仅在 windows 操作系统上有效:
在控制台窗口上选中命令行
在命令行窗口上按 “ctrl + break” 命令
然后会生成 dump 文件,dump 文件的内容会被打印在命令行窗口上。
注意1: 有几款笔记本(比如 lenovo t 系列)已经取消了 “break” 键,在这种情况下你不得不用谷歌搜索与 break 键功能类似的键,我发现 “function key + b” 键与 break 键的功能相同,因此我用 “ctrl + fn + b” 键来生成 dump 文件。
注意2: 用上述方式有一个缺点就是 dump 文件的内容会被打印到控制台上,没有 dump 文件的话,我们很难用分析工具比如来分析 dump 文件。因此你可以使用以下命令将 dump 文件的内容输出到文本文件当中,比如你的应用程序名字叫 samplethreadprogram ,那么通常使用的命令如下:
java -classpath . samplethreadprogram
将 dump 文件的内容输出到文本文件的命令如下:
java -classpath . samplethreadprogram > c:\workspace\threaddump.txt 2>&1
当你按下 “ctrl + break” 键之后,dump 文件会被保存到 c:\workspace\threaddump.txt 里。
6. threadmxbean
从 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()); } }
7. apm tool – app dynamics
一些应用性能监控工具提供了生成 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 版本等等。