乐趣区

JVM问题排查工具ServiceabilityAgent介绍

本文首发于微信公众号:javaadu

简单介绍

构建高性能的 Java 应用过程中,必然会遇到各种各样的问题,像 CPU 飙高、内存泄漏、应用奔溃,以及其他疑难杂症,这时可以使用 Serviceability Agent(SA)。SA 是 JDK 提供的一个强大的调试工具集,适用于语言层和虚拟机层,支持调试运行着的 Java 进程、core 文件和虚拟机 crash 之后的 dump 文件。

SA 的优点:可以呈现出类对象、能够识别出 Java 堆、堆边界、堆内对象、载入的类描述、栈内存、线程状态等信息。

安装

首先,我使用的操作系统版本是:macOS 10.12.6 进。SA 提供了两个调试工具:图形化的调试工具(HSDB)和命令行工具(CLHSDB)。这里我们演示下如何在 Mac 下启动 SA HSDB。

  1. 设置 JAVA_HOME 变量:export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/
  2. SA HSDB 的入口在 $JAVA_HOME/lib/sa-jdi.jar 中,main 方法在 sun.jvm.hotspot.HSDB 中,因此使用命令:sudo java -cp $JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.HSDB,就可以启动 HSDB 调试器(入下图所示)

使用模式

单击左上角的 File 按钮可以看到:下拉框里指出了 SA HSDB 的三种使用模式:

  1. 链接到本地 Hotspot 进程上;
  2. 链接到 core 文件;
  3. 连接到远程的服务器进行 Debug;

入门示例

这里我以自己维护的一个 Java 应用为例,演示了 SA HSDB 最重要的一些功能。我在本地启动了该服务,使用 jps -l 命令可以看到该服务的 PID 是 51926,我使用第一种调试模式。

SA 是快照调试器,因此,当在上图中点击 OK 的时候,account 的 Java 进程会被暂停,直到我们断开对该进程的调试,而 SA HSDB 显示的则是 SA 刚刚链接上 account 进程那个时间点的进程快照,入下图所示。

常用工具

左侧的下拉列表主要是一些常用的工具,分别介绍如下【其他功能暂时不常用,可以遇到问题了再研究】:

  1. 类浏览器(Class Browser):可以查看 account 的 Java 进程中载入的类;遇到 OOM 异常时,可以使用这个工具分析有哪些类是不需要载入的,当然,也可以分析希望载入但是没载入的情况;

  2. 死锁检测(Deadlock Detection):检测 Java 代码层面的死锁,如果线程中存在死锁,则会显示线程死锁的信息和他们等待的锁;
  3. 对象检视器(Interceptor):可以查看 Java 线程对象的基本信息,也可以查看虚拟机内部的 C ++ 结构体信息;

  4. 对象直方图(Object Histogram):可以查看当前堆内存中对象的直方图,该工具在排查内存泄漏和 OOM 类问题的时候非常有效

快捷图标

右侧的小窗口上面有四个图表,是一些快捷方式;分别介绍如下:

  1. 进程检视器:给出线程对象的 VM 中间表示形式(即开发者可以看懂的格式)
  2. 栈内存:显示选中进程的栈内存数据

    • 左起第 1 栏是内存地址,请让我提醒一下本文里提到“内存地址”的地方都是指虚拟内存意义上的地址,不是“物理内存地址”,请不要弄混了这俩概念;
    • 第 2 栏是该地址上存的数据,以字宽为单位,本文例子中我是在 macOS 上跑 64 位的 JDK8 的 HotSpot VM,字宽是 64 位(8 字节);
    • 第 3 栏是对数据的注释,竖线表示范围,横线或斜线连接范围与注释文字
  3. 栈调用路径:显示线程的调用路径,可以看到方法名和地址,并能超链到方法的详细信息
  4. 线程的基本信息:包括线程状态、线程 ID 等等

SA 的其他工具

  1. FinalizerInfo:该工具可用于打印出目标虚拟机所有可销毁对象的详细信息;
  2. HeapDumper:该工具可以用 hprof 格式转储 Java 堆的快照信息(类似于 jmap 命令);
  3. 永生代信息统计(PermStat):该工具用于打印出目标虚拟机中永生代的统计信息;Obje
  4. PMap:该工具用于打印出目标虚拟机进程的内存映射信息;
  5. 对象直方图(Object Histogram):对象直方图不仅可以在 HSDB 和 CLHSDB 中使用,还可以单独使用;
  6. OQL:该工具提供了类似脚本语言的命令,可以通过执行结构化对象查询语句,可以像写 SQL 一样,在 Java 堆中查找指定的对象;
  7. ClassDump:使用该工具可以导出目标虚拟机进程加载的类。

参考资料

  1. 《Java 性能调优指南》
  2. Java ServiceabilityAgent(HSDB)使用和分析
  3. 借 HSDB 来探索 HotSpot VM 的运行时数据
  4. Java 七武器系列长生剑 — Java 虚拟机的显微镜 Serviceability Agent

本号专注于后端技术、JVM 问题排查和优化、Java 面试题、个人成长和自我管理等主题,为读者提供一线开发者的工作和成长经验,期待你能在这里有所收获。

退出移动版