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/jmxrmijConsole 优缺点
优点:
✓ 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
黄色 → SLEEPINGCPU 性能分析(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 对比
| 维度 | jConsole | VisualVM |
|---|---|---|
| 安装 | 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/内存 profiling | Profiler、HeapWalker、OQL、死锁检测 |
推荐用法:先用 jConsole 做快速监控,定位问题后用 VisualVM 做深度分析。
下一节,我们来看 MAT(堆分析/内存泄漏排查)。
