Skip to content

jConsole/VisualVM 使用

GUI 工具:可视化诊断的窗口

命令行工具适合快速定位,但 GUI 工具提供了更直观、更全面的视角。这一节介绍 JDK 自带的两个 GUI 工具:jConsole 和 VisualVM。

jConsole:JVM 监控台

简介

jConsole(Java Monitoring and Management Console)是 JDK 自带的 JMX(Java Management Extensions)图形化监控工具。通过 JMX 连接,可以实时监控内存、线程、类加载、CPU 等信息。

jConsole 连接方式:
1. 本地连接:直接选择 Java 进程
2. 远程连接:JMX 连接字符串

启动 jConsole

bash
# 方式一:命令行启动
jconsole

# 方式二:指定进程
jconsole <pid>

# 方式三:远程连接
jconsole service:jmx:rmi:///jndi/rmi://hostname:port/jmxrmi

监控概览

连接成功后,jConsole 显示六个标签页:

概览(Overview)
  ├── 堆内存使用
  ├── 线程
  ├── 类
  ├── CPU 使用率
  └── VM 摘要

内存(Memory)
  ├── 堆内存图表
  ├── 各内存池使用情况
  └── 内存池详细信息

线程(Threads)
  ├── 活动线程数
  ├── 峰值线程数
  └── 线程列表和状态

类(Classes)
  ├── 已加载类总数
  └── 类卸载统计

VM 摘要(VM Summary)
  ├── JVM 参数
  ├── 系统属性
  └── 运行时间

MBeans
  ├── MBean 树形结构
  └── 操作和属性管理

内存监控

内存页是最常用的监控页面:

内存监控图表:
  X 轴:时间
  Y 轴:内存使用量(MB)

图表区域:
  Heap Memory Usage     → 堆内存使用曲线
  Non-Heap Memory Usage → 非堆内存使用(元空间等)

点击「执行 GC」按钮可以手动触发垃圾回收,对比前后内存变化。

线程监控

线程页显示所有线程的实时状态:

线程图表:
  活动线程数(实时)
  峰值线程数(历史最高)

线程列表:
  名称 | 状态 | 是否守护线程 | CPU 时间

状态分类:
  RUNNABLE   → 正在运行
  BLOCKED     → 阻塞等待锁
  WAITING     → 等待
  TIMED_WAITING → 限时等待

点击具体线程可以查看堆栈。

检测死锁

线程页有一个「检测死锁」按钮:

点击「检测死锁」后:
  → 分析所有线程的锁等待关系
  → 如果发现死锁,列出:
       1. 死锁线程
       2. 持有的锁
       3. 等待的锁

jConsole + JMX 远程监控

生产环境常用 JMX 远程监控:

bash
# JVM 启动时开启 JMX
java -Dcom.sun.management.jmxremote \
     -Dcom.sun.management.jmxremote.port=9999 \
     -Dcom.sun.management.jmxremote.authenticate=false \
     -Dcom.sun.management.jmxremote.ssl=false \
     -Dcom.sun.management.jmxremote.local.only=false \
     -Djava.rmi.server.hostname=<server-ip> \
     -jar myapp.jar

# 然后用 jConsole 连接
jconsole service:jmx:rmi:///jndi/rmi://server-ip:9999/jmxrmi

jConsole 优缺点

优点:
✓ JDK 自带,无需安装
✓ 轻量级,启动快
✓ 实时监控,界面直观
✓ 支持 JMX 远程监控

缺点:
✗ 功能相对基础
✗ 不支持分析堆转储文件
✗ CPU/内存分析能力有限

VisualVM:更强大的可视化工具

简介

VisualVM 是 NetBeans 平台上的可视化工具,提供了比 jConsole 更丰富的功能:

VisualVM 核心功能:
1. CPU 性能分析(Profiler)
2. 内存分析(HeapWalker)
3. 线程分析
4. 堆转储分析
5. GC 监控
6. MBean 浏览器

安装

bash
# JDK 8 及之前:VisualVM 已包含在 JDK 中
jvisualvm

# JDK 9+:需要单独下载
# https://visualvm.github.io/
# 下载后解压,运行 bin/visualvm

主界面

VisualVM 主界面:

左侧「应用程序」面板:
  ├── 本地(Local)
  │      └── 列出本地所有 Java 进程
  └── 远程(Remote)
         └── 添加远程主机

右侧「标签页」:
  ├── 概述(Overview)
  ├── 监视(Monitor)
  ├── 线程(Threads)
  ├── 取样器(Sampler)
  └── 抽样器(Profiler)

概述页

概述页显示 JVM 基本信息:

概述页包含:
1. PID、主机名
2. 主类名
3. JVM 参数
4. 系统属性
5. 启动时间和运行时间

监视页

监视页提供实时监控图表:

监视页图表:
  CPU → CPU 使用率折线图
  堆 → 堆内存使用曲线
  类 → 已加载类数量
  线程 → 活动线程数

快捷操作:
  「堆 Dump」 → 生成堆转储文件
  「线程 Dump」 → 生成线程转储
  「执行 GC」 → 手动触发 GC

线程页

线程页显示所有线程的状态:

线程页功能:
1. 线程列表(名称、状态、守护线程、CPU 时间)
2. 线程状态分布饼图
3. 线程堆栈查看
4. 死锁检测
5. 线程时间线视图

时间线视图(Timeline):
  时间轴 → 线程状态变化图
  颜色标识:
    绿色 → RUNNABLE
    蓝色 → WAITING / TIMED_WAITING
    红色 → BLOCKED
    黄色 → SLEEPING

CPU 性能分析(Profiler)

Profiler 是 VisualVM 最强大的功能之一:

bash
# 启动 CPU 采样
1. 选择「CPU」标签
2. 点击「CPU」按钮开始采样
3. 执行被测操作
4. 点击「CPU」按钮停止
5. 查看结果

CPU 分析结果展示:

热点方法视图:
  方法名                        自调用时间 | 总调用时间
  com.example.Service.query()      1200ms  |    1500ms
  java.sql.Connection.prepareStatement  200ms  |    800ms
  ...
调用树视图(Call Tree):
  Root
    └─ main()
       └─ com.example.App.run()
          └─ com.example.Service.query()
             ├─ java.sql.Driver.connect()   300ms
             └─ java.sql.Statement.execute()  900ms

内存分析

VisualVM 自带 HeapWalker,可以分析堆转储:

内存分析步骤:
1. 监视页 → 点击「堆 Dump」
2. 进入 HeapWalker 标签
3. 选择分析维度:
   - 类(Classes)
   - 实例(Instances)
   - OQL 查询(OQL Console)

OQL 查询

OQL(Object Query Language)允许用 SQL-like 语法查询堆:

sql
-- 查找所有 String 实例
SELECT x FROM java.lang.String x

-- 查找包含特定内容的 String
SELECT x FROM java.lang.String x WHERE x.toString().contains("error")

-- 查找大于 1MB 的 char[] 数组
SELECT x FROM char[] x WHERE x.length > 1048576

-- 查找特定类的所有实例
SELECT x FROM com.example.MyClass x WHERE x.field = "someValue"

VisualVM 插件

VisualVM 支持插件扩展:

常用插件:
1. Visual GC → 更详细的 GC 可视化
2. Thread Inspector → 更丰富的线程信息
3. Memory Pool Analyzer → 内存池分析

安装插件:
  工具 → 插件 → 可用插件 → 选择安装

VisualVM 与 jConsole 对比

维度jConsoleVisualVM
安装JDK 自带JDK 8 自带,JDK 9+ 需单独下载
功能基础监控更全面,含 Profiler
CPU 分析
内存分析实时监控实时 + 堆转储分析
线程分析基础更丰富,含时间线
OQL 查询
插件支持

实战:使用 VisualVM 分析性能问题

场景:应用响应慢

bash
# 1. 启动 VisualVM
jvisualvm

# 2. 连接目标应用
# 左侧双击本地进程或添加远程进程

# 3. 查看 CPU 图表
# 监视页 → CPU 使用率是否持续高?
# 如果是,进入下一步

# 4. CPU 采样
# Profiler → CPU → 开始

# 5. 复现问题(访问接口/执行操作)

# 6. 停止采样
# 查看热点方法列表

# 7. 分析结果
# - 找出占用 CPU 最多的方法
# - 查看调用树,确定调用链路
# - 定位需要优化的代码

场景:内存持续增长(疑似泄漏)

bash
# 1. 启动 VisualVM,连接应用

# 2. 观察堆内存曲线
# 监视页 → 堆图表
# 每次 GC 后堆内存是否在持续上升?

# 3. 生成堆转储
# 监视页 → 点击「堆 Dump」

# 4. 分析 HeapWalker
# 进入 HeapWalker → 类视图
# 按「总大小」排序,找出占用最大的类

# 5. 查看实例
# 选择可疑类 → 右键「显示实例」
# 查看实例数量和对象保留

# 6. 使用 OQL 进一步分析
# OQL Console → 编写查询

本节小结

jConsole 和 VisualVM 核心要点:

工具适用场景核心功能
jConsole快速监控、本地/远程 JMX内存、线程、GC 实时监控
VisualVM深度分析、CPU/内存 profilingProfiler、HeapWalker、OQL、死锁检测

推荐用法:先用 jConsole 做快速监控,定位问题后用 VisualVM 做深度分析。

下一节,我们来看 MAT(堆分析/内存泄漏排查)

基于 VitePress 构建