# JVM GUI 工具

Java 程序员免不了故障排查工作,所以经常需要使用一些 JVM 工具。

本文系统性的介绍一下常用的 JVM GUI 工具。

# 1. jconsole

jconsole 是 JDK 自带的 GUI 工具。jconsole(Java Monitoring and Management Console) 是一种基于 JMX 的可视化监视与管理工具

jconsole 的管理功能是针对 JMX MBean 进行管理,由于 MBean 可以使用代码、中间件服务器的管理控制台或所有符合 JMX 规范的软件进行访问。

注意:使用 jconsole 的前提是 Java 应用开启 JMX。

# 1.1. 开启 JMX

Java 应用开启 JMX 后,可以使用 jconsolejvisualvm 进行监控 Java 程序的基本信息和运行情况。

开启方法是,在 java 指令后,添加以下参数:

-Dcom.sun.management.jmxremote=true
-Dcom.sun.management.jmxremote.ssl=false
-Dcom.sun.management.jmxremote.authenticate=false
-Djava.rmi.server.hostname=127.0.0.1
-Dcom.sun.management.jmxremote.port=18888
  • -Djava.rmi.server.hostname - 指定 Java 程序运行的服务器
  • -Dcom.sun.management.jmxremote.port - 指定 JMX 服务监听端口

# 1.2. 连接 jconsole

如果是本地 Java 进程,jconsole 可以直接绑定连接。

如果是远程 Java 进程,需要连接 Java 进程的 JMX 端口。

Connecting to a JMX Agent Using the JMX Service URL

# 1.3. jconsole 界面

进入 jconsole 应用后,可以看到以下 tab 页面。

  • 概述 - 显示有关 Java VM 和监视值的概述信息。
  • 内存 - 显示有关内存使用的信息。内存页相当于可视化的 jstat 命令。
  • 线程 - 显示有关线程使用的信息。
  • - 显示有关类加载的信息。
  • VM 摘要 - 显示有关 Java VM 的信息。
  • MBean - 显示有关 MBean 的信息。

img

# 2. jvisualvm

jvisualvm 是 JDK 自带的 GUI 工具。jvisualvm(All-In-One Java Troubleshooting Tool) 是多合一故障处理工具。它支持运行监视、故障处理、性能分析等功能。

个人觉得 jvisualvm 比 jconsole 好用。

# 2.1. jvisualvm 概述页面

jvisualvm 概述页面可以查看当前 Java 进程的基本信息,如:JDK 版本、Java 进程、JVM 参数等。

img

# 2.2. jvisualvm 监控页面

在 jvisualvm 监控页面,可以看到 Java 进程的 CPU、内存、类加载、线程的实时变化。

img

# 2.3. jvisualvm 线程页面

jvisualvm 线程页面展示了当前的线程状态。

img

jvisualvm 还可以生成线程 Dump 文件,帮助进一步分析线程栈信息。

img

# 2.4. jvisualvm 抽样器页面

jvisualvm 可以对 CPU、内存进行抽样,帮助我们进行性能分析。

image-20200730150648010

# 3. MAT

MAT (opens new window) 即 Eclipse Memory Analyzer Tool 的缩写。

MAT 本身也能够获取堆的二进制快照。该功能将借助 jps 列出当前正在运行的 Java 进程,以供选择并获取快照。由于 jps 会将自己列入其中,因此你会在列表中发现一个已经结束运行的 jps 进程。

MAT 可以独立安装(官方下载地址 (opens new window)),也可以作为 Eclipse IDE 的插件安装。

# 3.1. MAT 配置

MAT 解压后,安装目录下有个 MemoryAnalyzer.ini 文件。

MemoryAnalyzer.ini 中有个重要的参数 Xmx 表示最大内存,默认为:-vmargs -Xmx1024m

如果试图用 MAT 导入的 dump 文件超过 1024 M,会报错:

An internal error occurred during: "Parsing heap dump from XXX"

此时,可以适当调整 Xmx 大小。如果设置的 Xmx 数值过大,本机内存不足以支撑,启动 MAT 会报错:

Failed to create the Java Virtual Machine

# 3.2. MAT 分析

img

点击 Leak Suspects 可以进入内存泄漏页面。

(1)首先,可以查看饼图了解内存的整体消耗情况

img

(2)缩小范围,寻找问题疑似点

img

可以点击进入详情页面,在详情页面 Shortest Paths To the Accumulation Point 表示 GC root 到内存消耗聚集点的最短路径,如果某个内存消耗聚集点有路径到达 GC root,则该内存消耗聚集点不会被当做垃圾被回收。

为了找到内存泄露,我获取了两个堆转储文件,两个文件获取时间间隔是一天(因为内存只是小幅度增长,短时间很难发现问题)。对比两个文件的对象,通过对比后的结果可以很方便定位内存泄露。

MAT 同时打开两个堆转储文件,分别打开 Histogram,如下图。在下图中方框 1 按钮用于对比两个 Histogram,对比后在方框 2 处选择 Group By package,然后对比各对象的变化。不难发现 heap3.hprof 比 heap6.hprof 少了 64 个 eventInfo 对象,如果对代码比较熟悉的话想必这样一个结果是能够给程序员一定的启示的。而我也是根据这个启示差找到了最终内存泄露的位置。 img

# 4. JProfile

JProfiler (opens new window) 是一款性能分析工具。

由于它是收费的,所以我本人使用较少。但是,它确实功能强大,且方便使用,还可以和 Intellij Idea 集成。

image-20200730152158398

# 5. Arthas

Arthas (opens new window) 是 Alibaba 开源的 Java 诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪 Java 代码;实时监控 JVM 状态。

Arthas 支持 JDK 6+,支持 Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

img

# 5.1. Arthas 基础命令

  • help——查看命令帮助信息
  • cat (opens new window)——打印文件内容,和 linux 里的 cat 命令类似
  • echo (opens new window)–打印参数,和 linux 里的 echo 命令类似
  • grep (opens new window)——匹配查找,和 linux 里的 grep 命令类似
  • tee (opens new window)——复制标准输入到标准输出和指定的文件,和 linux 里的 tee 命令类似
  • pwd (opens new window)——返回当前的工作目录,和 linux 命令类似
  • cls——清空当前屏幕区域
  • session——查看当前会话的信息
  • reset (opens new window)——重置增强类,将被 Arthas 增强过的类全部还原,Arthas 服务端关闭时会重置所有增强过的类
  • version——输出当前目标 Java 进程所加载的 Arthas 版本号
  • history——打印命令历史
  • quit——退出当前 Arthas 客户端,其他 Arthas 客户端不受影响
  • stop——关闭 Arthas 服务端,所有 Arthas 客户端全部退出
  • keymap (opens new window)——Arthas 快捷键列表及自定义快捷键

# 5.2. Arthas jvm 相关命令

# 5.3. Arthas class/classloader 相关命令

# 5.4. Arthas monitor/watch/trace 相关命令

请注意,这些命令,都通过字节码增强技术来实现的,会在指定类的方法中插入一些切面来实现数据统计和观测,因此在线上、预发使用时,请尽量明确需要观测的类、方法以及条件,诊断结束要执行 stop 或将增强过的类执行 reset 命令。

# 6. 参考资料