Java中抓取 Thread Dumps 的方式汇总

Thread dumps(线程转储)能帮助我们判断 CPU 峰值、死锁、内存异常、应用反应迟钝、响应时间变长和其他系统问题。一些在线的分析工具比如 http://fastthread.io/ 也能帮助我们分析和定位问题,但是这些工具都要求有一个 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 文件的话,我们很难用分析工具比如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 里。

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 版本等等。

(0)

相关推荐

  • MySQL的mysqldump工具用法详解

    导出要用到MySQL的mysqldump工具,基本用法是: 复制代码 代码如下: shell> mysqldump [OPTIONS] database [tables] 如果你不给定任何表,整个数据库将被导出.   通过执行mysqldump --help,你能得到你mysqldump的版本支持的选项表.   注意,如果你运行mysqldump没有--quick或--opt选项,mysqldump将在导出结果前装载整个结果集到内存中,如果你正在导出一个大的数据库,这将可能是一个问题.   my

  • C++软件添加dump调试打印日志(推荐)

    C++软件添加dump调试打印日志(推荐) #include <DbgHelp.h> #pragma comment(lib, "dbghelp.lib") LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *pExceptionInfo) { //cout << "Enter TopLevelExceptionFilter Function" << en

  • MySQL的备份工具mysqldump的基础使用命令总结

    MySQL数据库的备份工具有很多,不过这里介绍的是一个小巧好用的mysqldump工具,位于数据库目录下bin/mysqldump.exe.这几天用phpMyAdmin备份数据库的时候出现乱码,反复在本地跟远程的Dreamhost空间上测试了数据库,但是还是导出数据库会出现乱码,应该是phpMyAdmin出现的问题,数据库本身没有问题.扯远咯,呵呵.我Google到的关于mysqldump工具的相关用法. 如果主机主机支持 Shell 的话,可以 SSH 登陆主机,执行如下的命令实现备份与恢复,

  • 在MySQLDump中使用-w语句进行备份的方法

    我们在用mysqldump备份数据时,有个选项是 –where / -w,可以指定备份条件,这个选项的解释是: -w, --where=name Dump only selected records. Quotes are mandatory 我们可以做个测试,例如: mysqldump --single-transaction -w ' id < 10000 ' mydb mytable > mydump.sql 这时候就可以备份出mytable表中 id< 10000 的所有记录了.

  • mysqldump命令导入导出数据库方法与实例汇总

    mysqldump命令的用法 1.导出所有库 系统命令行 mysqldump -uusername -ppassword --all-databases > all.sql 2.导入所有库 mysql命令行 mysql>source all.sql; 3.导出某些库 系统命令行 mysqldump -uusername -ppassword --databases db1 db2 > db1db2.sql 4.导入某些库 mysql命令行 mysql>source db1db2.s

  • MySQL数据库使用mysqldump导出数据详解

    mysqldump是mysql用于转存储数据库的客户端程序.它主要产生一系列的SQL语句,可以封装到文件,该文件包含有所有重建您的数据库所需要的 SQL命令如CREATE DATABASE,CREATE TABLE,INSERT等等.可以用来实现轻量级的快速迁移或恢复数据库.是mysql数据库实现逻辑备份的一种方式. 在日常维护工作当中经常会需要对数据进行导出操作,而mysqldump是导出数据过程中使用非常频繁的一个工具:它自带的功能参数非常多,文章中会列举出一些常用的操作,在文章末尾会将所有

  • Java中抓取 Thread Dumps 的方式汇总

    Thread dumps(线程转储)能帮助我们判断 CPU 峰值.死锁.内存异常.应用反应迟钝.响应时间变长和其他系统问题.一些在线的分析工具比如 http://fastthread.io/ 也能帮助我们分析和定位问题,但是这些工具都要求有一个 dump 文件.因此在这篇文章当中,我总结了7中抓取 Java Thread Dumps 文件的方式. 1. jstack jstack 是一个抓取 thread dump 文件的有效的命令行工具,它位于 JDK 目录里的 bin 文件夹下(JDK_HO

  • java 中遍历取值异常(Hashtable Enumerator)解决办法

    java 中遍历取值异常(Hashtable Enumerator)解决办法 用迭代器取值时抛出的异常:java.util.NoSuchElementException: Hashtable Enumerator 示例代码 //使用迭代器遍历 Iterator<String> it = tableProper.stringPropertyNames().iterator(); sqlMap = new HashMap<String,String>(); while(it.hasNe

  • 浅析Java中Runnable和Thread的区别

    线程的起动并不是简单的调用了你的RUN方法,而是由一个线程调度器来分别调用你的所有线程的RUN方法, 我们普通的RUN方法如果没有执行完是不会返回的,也就是会一直执行下去,这样RUN方法下面的方法就不可能会执行了,可是线程里的RUN方法却不一样,它只有一定的CPU时间,执行过后就给别的线程了,这样反复的把CPU的时间切来切去,因为切换的速度很快,所以我们就感觉是很多线程在同时运行一样. 你简单的调用run方法是没有这样效果的,所以你必须调用Thread类的start方法来启动你的线程.所以你启动

  • java多线程抓取铃声多多官网的铃声数据

    一直想练习下java多线程抓取数据. 有天被我发现,铃声多多的官网(http://www.shoujiduoduo.com/main/)有大量的数据. 通过观察他们前端获取铃声数据的ajax http://www.shoujiduoduo.com/ringweb/ringweb.php?type=getlist&listid={类别ID}&page={分页页码} 很容易就能发现通过改变 listId和page就能从服务器获取铃声的json数据, 通过解析json数据, 可以看到都带有{&q

  • Java中实现线程的三种方式及对比_动力节点Java学院整理

    Java中创建线程主要有三种方式: 一.继承Thread类创建线程类 (1)定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务.因此把run()方法称为执行体. (2)创建Thread子类的实例,即创建了线程对象. (3)调用线程对象的start()方法来启动该线程. package com.thread; public class FirstThreadTest extends Thread{ int i = 0; //重写run方法,run方法的方

  • java代码抓取网页邮箱的实现方法

    实现思路: 1.使用java.net.URL对象,绑定网络上某一个网页的地址 2.通过java.net.URL对象的openConnection()方法获得一个HttpConnection对象 3.通过HttpConnection对象的getInputStream()方法获得该网络文件的输入流对象InputStream 4.循环读取流中的每一行数据,并由Pattern对象编译的正则表达式区配每一行字符,取得email地址 package cn.sdhzzl; import java.io.Buf

  • java中ThreadLocal取不到值的两种原因

    1.两种原因 第一种,也是最常见的一种,就是多个线程使用ThreadLocal 第二种,类加载器不同造成取不到值,本质原因就是不同类加载器造成多个ThreadLocal对象 public class StaticClassLoaderTest { protected static final ThreadLocal<Object> local = new ThreadLocal<Object>(); //cusLoader加载器加载的对象 private Test3 test3;

  • Java中生成随机数的4种方式与区别详解

    目录 在 Java 中,生成随机数的场景有很多,所以本文我们就来盘点一下 4 种生成随机数的方式,以及它们之间的区别和每种生成方式所对应的场景. 1.Random Random 类诞生于 JDK 1.0,它产生的随机数是伪随机数,也就是有规则的随机数.Random 使用的随机算法为 linear congruential pseudorandom number generator (LGC) 线性同余法伪随机数.在随机数生成时,随机算法的起源数字称为种子数(seed),在种子数的基础上进行一定的

  • Java中定时任务的6种实现方式

    目录 1.线程等待实现 2.JDK自带Timer实现 2.1 核心方法 2.2使用示例 2.2.1指定延迟执行一次 2.2.2固定间隔执行 2.2.3固定速率执行 2.3 schedule与scheduleAtFixedRate区别 2.3.1schedule侧重保持间隔时间的稳定 2.3.2scheduleAtFixedRate保持执行频率的稳定 2.4 Timer的缺陷 3.JDK自带ScheduledExecutorService 3.1 scheduleAtFixedRate方法 3.2

  • java中HashMap的7种遍历方式与性能分析

    目录 1.遍历方式 1.1 迭代器 EntrySet 1.2 迭代器 KeySet 1.3 ForEach EntrySet 1.4 ForEach KeySet 1.5 Lambda 表达式 1.6 Stream API 单线程 1.7 Stream API 多线程 1.8 代码汇总 2.性能分析 2.1 引入依赖 2.2 编写测试类 2.3 测试结果 2.4 分析 2.5 总结 1.遍历方式 1.1 迭代器 EntrySet /** * 1. 迭代器 EntrySet */ @Test pu

随机推荐