当前位置: 首页 > news >正文

Java 性能监控工具详解:JConsole、VisualVM 和 Java Mission Control

在 Java 应用程序的开发和维护过程中,性能监控和故障诊断是至关重要的。本文将详细介绍三款常用的 Java 性能监控工具:JConsole、VisualVM 和 Java Mission Control(JMC),并探讨它们的功能和使用方法。

1 JConsole

1.1 简介

JConsole(Java Monitoring and Management Console)是一款基于 JMX(Java Management Extensions)的可视化监控管理工具。JMX 是 Java 管理系统中的一个标准,JConsole 则是 JMX 的一个实现类。JConsole 可以用于监控 Java 应用程序的运行状态,包括内存使用、线程状态、类加载、垃圾回收(GC)等,还可以进行一些基本的性能分析。

1.2 连接 Java 程序

JConsole 位于 %JAVA_HOME%/bin 目录下。启动 JConsole 后,会显示本机正在运行的 Java 程序,用户可以选择一个程序进行连接。此外,JConsole 还支持远程连接,监控服务器上的 Java 程序。远程连接需要在启动 Java 程序时添加以下参数:

-Dcom.sun.management.jmxremote
-Dcom.sun.management.jmxremote.port=<PORT>
-Dcom.sun.management.jmxremote.authenticate=false
-Dcom.sun.management.jmxremote.ssl=false

其中,<PORT> 是 JMX 代理监听的端口号,authenticate=false 表示不需要身份验证,ssl=false 表示不使用 SSL 加密连接。

1.3 功能概述

使用 JConsole 连接本地 Java 程序后,可以在 概述 面板中查看程序的运行时概况。主要包括以下四项信息的曲线图:

  • 堆内存使用量:显示 Java 堆内存的使用情况。
  • 线程:显示当前活动的线程数量。
  • :显示已加载的类数量。
  • CPU 占用率:显示程序的 CPU 使用率。

这些曲线图可以帮助开发者快速了解程序的整体运行状态。
在这里插入图片描述

1.3.1 内存监控

JConsole 的内存监控功能相当于可视化的 jstat 命令,能够实时监控 Java 堆内存的使用情况。具体可以细化为以下几个区域:

  • Eden 区:新创建的对象首先分配在 Eden 区。
  • Survivor 区:存活的对象从 Eden 区移动到 Survivor 区。
  • 老年代:长时间存活的对象最终会被移动到老年代。

示例代码:观察内存变化
以下代码用于模拟内存分配,并通过 JConsole 观察内存变化:

/*** VM参数: -Xms100m -Xmx100m -XX:+UseSerialGC*/
class JConcoleRAMMonitor {/**** 内存占位符对象,一个 OOMObject 大约占 64KB*/static class OOMObject {public byte[] placeholder = new byte[64 * 1024];}public static void fillHeap(int num) throws InterruptedException {List<OOMObject> list = new ArrayList<OOMObject>();for (int i = 0; i < num; i++) {// 稍作延时,令监视曲线的变化更加明显Thread.sleep(300);list.add(new OOMObject());}System.gc(); // 手动触发垃圾回收}public static void main(String[] args) throws Exception {fillHeap(2000); // 填充 2000 个对象}
}

运行结果分析

  • Eden 区趋势:运行代码后,Eden 区的内存使用量呈折线趋势增长。
    在这里插入图片描述

  • 执行 GC 后:点击 JConsole 中的「执行 GC」按钮后,Eden 区的对象被回收,存活的对象被移动到老年代,此时老年代的柱状图会达到峰值。
    在这里插入图片描述

1.3.2 线程监控

JConsole 的线程监控功能相当于可视化的 jstack 命令,能够显示应用程序内的线程状态。具体功能包括:

  • 线程数量:显示当前活动的线程数量。
  • 线程详情:左下方列出程序中所有的线程,点击线程名称可以查看线程的栈信息。
  • 死锁检测:JConsole 可以快速定位死锁问题。

示例代码:死锁检测
以下代码模拟了一个典型的死锁场景:

class DeadLockDemo {private static final Object lock1 = new Object();private static final Object lock2 = new Object();public static void main(String[] args) {new Thread(() -> {synchronized (lock1) {System.out.println("线程1获取到了锁1");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock2) {System.out.println("线程1获取到了锁2");}}}).start();new Thread(() -> {synchronized (lock2) {System.out.println("线程2获取到了锁2");try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}synchronized (lock1) {System.out.println("线程2获取到了锁1");}}}).start();}
}

运行结果分析

  • 运行代码后,点击 JConsole 线程面板中的「检测到死锁」按钮,可以查看线程的死锁信息。
    在这里插入图片描述

1.3.3 类加载情况

在 JConsole 的 面板中,可以查看以下信息:

  • 已加载的类数量:显示当前已加载的类数量。
  • 已卸载的类数量:显示已卸载的类数量。

这些信息可以帮助开发者了解应用程序的类加载行为。
在这里插入图片描述

1.3.4 VM 概要

在 JConsole 的 VM 概要 面板中,可以查看当前应用程序的运行时环境信息,包括:

  • 虚拟机类型:如 HotSpot。
  • 虚拟机版本:如 JDK 版本号。
  • 堆信息:如堆内存的初始大小和最大大小。
  • 虚拟机参数:如启动时设置的 JVM 参数。

---

2. VisualVM

VisualVM(All-in-One Java Troubleshooting Tool)是一款集性能监控、故障诊断和分析于一体的工具。它不仅能够监控 Java 应用程序的运行状态,还支持生成堆转储快照、分析 CPU 和内存使用情况等功能。

2.1 安装与启动

2.1.1 下载与安装

VisualVM 的安装非常简单,访问其官方网站 https://visualvm.github.io 下载适合您操作系统的版本。安装完成后,启动 VisualVM,界面如下所示:

在这里插入图片描述

2.1.2 插件功能

VisualVM 支持插件扩展,用户可以通过以下步骤安装插件:

  1. 点击菜单栏中的 Tools -> Plugins
  2. 在可用插件列表中选择需要的插件,点击安装。

插件功能极大地扩展了 VisualVM 的能力,例如支持更多的监控指标、分析工具等。

在这里插入图片描述

2.2 生成与浏览堆转储快照

堆转储快照(Heap Dump)是分析内存问题的重要工具。VisualVM 提供了两种生成堆转储快照的方式:

2.2.1 方式一:右键生成

  1. 在应用程序面板中,右键点击目标应用程序。
  2. 选择 Heap Dump,VisualVM 会自动生成堆转储快照。
    在这里插入图片描述

2.2.2 方式二:监视面板生成

  1. 在应用程序面板中选择目标应用程序。
  2. 在“监视”面板中,点击 Heap Dump 按钮。
    在这里插入图片描述

2.2.3 保存堆转储快照

生成的堆转储快照默认是临时文件,关闭 VisualVM 后会被自动清理。如果需要保存快照文件,可以:

  1. heapdump 节点上右键点击。
  2. 选择 另存为,将堆转储快照保存到本地。

---

2.3 分析程序性能

VisualVM 提供了强大的性能分析功能,可以帮助开发者深入了解应用程序的 CPU 和内存使用情况。

2.3.1 CPU 分析

  1. 分析 profiler 面板中,点击 CPU 按钮。
  2. VisualVM 会开始记录应用程序执行的所有方法。
  3. 返回应用程序进行操作,操作结束后点击 停止 按钮。
  4. 分析结果会显示每个方法的执行次数和执行耗时。

2.3.2 内存分析

  1. 分析 profiler 面板中,点击 Memory 按钮。
  2. VisualVM 会开始记录应用程序的内存分配情况。
  3. 返回应用程序进行操作,操作结束后点击 停止 按钮。
  4. 分析结果会显示每个方法的内存分配情况。

---

3. Java Mission Control (JMC)

JMC 是一款集性能监控、故障诊断和分析于一体的工具,适用于 Java 应用程序的开发和生产环境。它提供了丰富的功能,包括 MBean 服务器监控、飞行记录器(JFR)等,能够帮助开发者深入分析应用程序的性能问题。

  • GitHub 地址:https://github.com/openjdk/jmc
  • 官方下载:https://jdk.java.net/jmc/8/

3.1 安装与启动

  1. 访问 https://jdk.java.net/jmc/8/ 下载 JMC。
  2. 解压下载的文件,启动 JMC。

启动后的界面如下所示:

在这里插入图片描述

3.2 MBean 服务器

MBean(Managed Bean)是 Java 管理扩展(JMX)的一部分,用于管理 Java 应用程序。通过 JMC 的 MBean 服务器功能,可以监控以下信息:

  • Java 堆使用率:显示堆内存的使用情况。
  • CPU 使用率:显示应用程序的 CPU 占用情况。
  • Live Set + Fragmentation:Live Set 表示存活对象的大小,Fragmentation 表示内存碎片的大小。

---

3.3 飞行记录器(Flight Recorder, JFR)

飞行记录器(JFR)是 JMC 提供的一项强大功能,能够记录应用程序在一段时间内的运行情况,并进行分析和展示。JFR 提供的数据质量通常比其他工具通过代理形式采样获得的更高。

3.3.1 启用 JFR

要使用 JFR,需要在启动 Java 程序时添加以下参数:

-XX:+UnlockCommercialFeatures -XX:+FlightRecorder

3.3.2 使用 JFR 进行性能记录

  1. 连接已启用 JFR 的 Java 程序。
  2. 启动飞行记录器,设置记录时间(例如 1 分钟)。
  3. 记录结束后,JMC 会自动打开记录文件。
    在这里插入图片描述在这里插入图片描述

3.3.3 JFR 的优势

  • 垃圾回收分析:JFR 不仅提供各分代的大小、收集次数和时间等“结果”类信息,还能显示内存中分配和回收的对象,提供“过程”类信息。
  • CPU 和内存分析:JFR 可以记录应用程序的 CPU 使用情况和内存分配情况,帮助开发者定位性能瓶颈。

3.4. 示例代码与分析

3.4.1 CPU 使用过高示例

以下代码模拟了一个 CPU 使用率过高的场景:

/*** 消耗 CPU 的线程* 不断循环进行浮点运算*/
private static void cpuHigh() {Thread thread = new Thread(() -> {Thread.currentThread().setName("cpu_high_thread");while (true) {double pi = 0;for (int i = 0; i < Integer.MAX_VALUE; i++) {pi += Math.pow(-1, i) / (2 * i + 1);}System.out.println("Pi: " + pi * 4);}});thread.start();
}

在这里插入图片描述

3.4.2 内存使用过高示例

以下代码模拟了一个内存使用率过高的场景:

/*** 不断新增 BigDecimal 信息到 list*/
private static void allocate() {new Thread(() -> {Thread.currentThread().setName("memory_allocate_thread");List<BigDecimal> list = new ArrayList<>();for (int i = 0; i < Integer.MAX_VALUE; i++) {try {Thread.sleep(1);} catch (InterruptedException e) {throw new RuntimeException(e);}list.add(new BigDecimal(i));}}).start();
}

在这里插入图片描述

3.4.3 分析结果

  • 内存面板:通过 JMC 的内存面板,可以看到 String 对象占用了最多的内存。
  • 线程页面:切换到线程页面,勾选相关复选框,可以查看内存分配情况和 CPU 使用情况。
  • 死锁检测:JMC 还可以检测并显示死锁信息。

4. 第三方工具

除了上述官方工具外,还有一些第三方工具也非常有用:

  • MAT(Memory Analyzer Tool):Java 堆内存分析工具。
  • GChisto:GC 日志分析工具。
  • GCViewer:GC 日志分析工具。
  • JProfiler:商用的性能分析利器。
  • Arthas:阿里开源诊断工具。
  • async-profiler:Java 应用性能分析工具,支持火焰图和跨平台。

5. 总结

本文介绍了三款常用的 Java 性能监控工具:JConsole、VisualVM 和 Java Mission Control。它们各自具有独特的功能和优势,能够帮助开发者更好地监控和诊断 Java 应用程序的性能问题。在实际开发中,可以根据具体需求选择合适的工具,并结合第三方工具进行更深入的分析和优化。

通过合理使用这些工具,开发者可以更高效地定位和解决性能瓶颈,确保 Java 应用程序的稳定运行。

6 思维导图

在这里插入图片描述

7 参考链接

JVM 性能监控工具之可视化篇

相关文章:

Java 性能监控工具详解:JConsole、VisualVM 和 Java Mission Control

在 Java 应用程序的开发和维护过程中&#xff0c;性能监控和故障诊断是至关重要的。本文将详细介绍三款常用的 Java 性能监控工具&#xff1a;JConsole、VisualVM 和 Java Mission Control&#xff08;JMC&#xff09;&#xff0c;并探讨它们的功能和使用方法。 1 JConsole 1…...

浏览器报错:您的连接不是私密连接,Kubernetes Dashboard无法打开

问题描述 部署完成Kubernetes Dashboard后&#xff0c;打开HTTPS的web页面&#xff0c;Chrome和Edge浏览器都无法正常加载页面&#xff0c;会提示您的连接不是私密连接的报错。 ​​​​​​​​​​​​ 原因&#xff1a; 浏览器不信任这些自签名的ssl证书&#xff0c;为了…...

用Python进行大数据处理:如何使用pandas和dask处理海量数据

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 随着数据量的爆炸式增长,大数据处理成为现代数据科学和工程领域的核心挑战。Python作为数据分析的重要工具,其生态系统中的pandas和dask库…...

机器人手眼标定

机器人手眼标定 一、机器人手眼标定1. 眼在手上标定基本原理2. 眼在手外标定基本原理 二、眼在手外标定实验三、标定精度分析 一、机器人手眼标定 要实现由图像目标点到实际物体上抓取点之间的坐标转换&#xff0c;就必须拥有准确的相机内外参信息。其中内参是相机内部的基本参…...

基于Springboot + vue实现的校园失物招领系统

&#x1f942;(❁◡❁)您的点赞&#x1f44d;➕评论&#x1f4dd;➕收藏⭐是作者创作的最大动力&#x1f91e; &#x1f496;&#x1f4d5;&#x1f389;&#x1f525; 支持我&#xff1a;点赞&#x1f44d;收藏⭐️留言&#x1f4dd;欢迎留言讨论 &#x1f525;&#x1f525;&…...

关于C语言初步的一些基础知识整理(2)

“本篇是对于C语言初步中一些基础知识的简单整理&#xff0c;内容较为琐碎&#xff0c;但实用” 在C语言中&#xff0c;格式控制符是用于指定数据输出格式的特殊字符&#xff0c;不同的数据类型有着其对应的格式控制符。具体的&#xff1a; %f 用于输出浮点型数据&#xff08…...

Linux驱动开发:深入理解I2C时序(二)

在Linux驱动开发中,I2C时序的理解和正确处理是保证I2C设备正常工作和通信的关键。I2C协议的时序特性决定了数据的有效传输和设备间的协作。因此,掌握I2C的时序细节,以及如何在Linux内核中进行时序处理,能够让开发者更好地处理设备通信问题。 本文将继续深入探讨I2C通信协议…...

逆向安卓抓包

打开Mumu网易&#xff0c;打开设置&#xff0c;打开其他&#xff0c;开启root权限 打开Mumu网易&#xff0c;找到apk安装藏航准备网.apk charles配置&#xff1a;proxy setting 端口9888 查看当地IP:help--->local IP address SSL Proxying Setting--->Add---->IP…...

Spring源码分析之事件机制——观察者模式(一)

目录 事件基类定义 事件监听器接口 事件发布者接口及实现 事件广播器实现 小小总结 Spring源码分析之事件机制——观察者模式&#xff08;一&#xff09;-CSDN博客 Spring源码分析之事件机制——观察者模式&#xff08;二&#xff09;-CSDN博客 Spring源码分析之事件机制…...

QT实现 端口扫描暂停和继续功能 3

上篇QT给端口扫描工程增加线程2-CSDN博客 为按钮pushButton_Stop添加clicked事件&#xff0c;功能为暂停扫描&#xff0c;并在暂停后显示继续按钮&#xff0c;点击继续按钮之后继续扫描 1.更新UI 添加继续按钮 点击转到槽则会自动声明 2. 更新 MainWindow.h 需要新增的部分…...

SHViT模型详解

模型简介 SHViT是一种创新的 单头视觉Transformer ,旨在优化计算效率和内存使用。它的核心设计理念围绕着消除传统视觉Transformer架构中的冗余元素,特别关注宏观和微观设计层面的问题。 SHViT采用了 1616的大跨度patchify stem 和 3阶段结构 ,这种独特的设计不仅有效减少…...

QGIS Server安装部署教程

一、QGIS 安装部署 1、下载安装QGIS链接如下图&#xff0c;选择最新的安装包文件QGIS-OSGeo4W-3.34.14-1.msi&#xff0c;下载完成后运行安装。 2、安装时选择QGIS安装路径不要带空格&#xff0c;此处会影响QGIS Server安装运行。 3、安装过程省略&#xff0c;安装完成后打…...

基于 Apache Commons Pool 实现的 gRPC 连接池管理类 GrpcChannelPool 性能分析与优化

基于 Apache Commons Pool 实现的 gRPC 连接池管理类 GrpcChannelPool 性能分析与优化 1. 输出关键信息的代码示例 日志记录方法 使用以下代码记录连接池的关键信息&#xff0c;帮助分析连接池的状态和性能瓶颈&#xff1a; import org.apache.commons.pool2.impl.GenericO…...

【C语言】

目录 第一个C语言程序题目实际应用程序要求输入描述输出描述示例 程序实现三级目录 第一个C语言程序 打开VS创建项目&#xff08;视图-解决方案管理器&#xff09;创建源文件&#xff08;后缀.c&#xff09;.c会按照C的语言编译代码 c #include <stdio.h> //std-标准 //…...

标题:利用Spring Boot构建JWT刷新令牌应用

标题&#xff1a;利用Spring Boot构建JWT刷新令牌应用 去发现同类优质开源项目:https://gitcode.com/ 一、项目介绍 在Java开发中&#xff0c;Spring Boot以其简洁的配置和强大的功能深受开发者喜爱。Spring Boot Refresh Token with JWT 是一个开源示例项目&#xff0c;它展…...

性能测试工具的原理与架构解析

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 在软件开发与运维领域&#xff0c;性能测试是确保系统稳定、高效运行的关键环节。性能测试工具作为实现这一目标的重要工具&#xff0c;通过模拟真实用户行为和负载…...

基于STM32的自动水满报警系统设计

目录 引言系统设计 硬件设计软件设计系统功能模块 水位检测模块报警模块自动控制模块控制算法 水位检测逻辑报警触发逻辑代码实现 水位检测模块报警控制模块自动控制逻辑系统调试与优化结论与展望 1. 引言 水满报警系统在家庭、农业、工业等领域广泛应用&#xff0c;通过实时…...

C语言 数组编程练习

1.将数组A的内容和数组B中的内容进行交换。&#xff08;数组一样大&#xff09; 2.创建一个整形数组&#xff0c;完成对数组的操作 实现函数Init()初始化数组全为0 实现print()打印数组的每个元素 实现reverse()函数完成数组元素的逆置 //2.创建一个整形数组&#xff0c;完…...

Windows 远程桌面连接Ubuntu操作 可以自由相互复制文件 粘贴板等

1.windows不用动&#xff0c;用IP和用户密码直接连 Ubuntu设置 详细参考&#xff1a;https://blog.csdn.net/qq_22370409/article/details/88914093 新建的用户需要加入sudo 使有权限。 效果 可以自由相互复制文件 粘贴板等。...

链表OJ题(一)

(一&#xff09;轮转数组 . - 力扣&#xff08;LeetCode&#xff09; 题目描述&#xff1a;给定一个整数数组 nums&#xff0c;将数组中的元素向右轮转 k 个位置&#xff0c;其中 k 是非负数。 示例一&#xff1a; 方法一&#xff1a;暴力求解 先用一个变量存储数组中的最后…...

变量 varablie 声明- Rust 变量 let mut 声明与 C/C++ 变量声明对比分析

一、变量声明设计&#xff1a;let 与 mut 的哲学解析 Rust 采用 let 声明变量并通过 mut 显式标记可变性&#xff0c;这种设计体现了语言的核心哲学。以下是深度解析&#xff1a; 1.1 设计理念剖析 安全优先原则&#xff1a;默认不可变强制开发者明确声明意图 let x 5; …...

基于大模型的 UI 自动化系统

基于大模型的 UI 自动化系统 下面是一个完整的 Python 系统,利用大模型实现智能 UI 自动化,结合计算机视觉和自然语言处理技术,实现"看屏操作"的能力。 系统架构设计 #mermaid-svg-2gn2GRvh5WCP2ktF {font-family:"trebuchet ms",verdana,arial,sans-…...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面&#xff0c;开源代码 作为一个电子罗盘模块&#xff0c;我们可以通过I2C从中获取偏航角yaw&#xff0c;相对于六轴陀螺仪的yaw&#xff0c;qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

376. Wiggle Subsequence

376. Wiggle Subsequence 代码 class Solution { public:int wiggleMaxLength(vector<int>& nums) {int n nums.size();int res 1;int prediff 0;int curdiff 0;for(int i 0;i < n-1;i){curdiff nums[i1] - nums[i];if( (prediff > 0 && curdif…...

【git】把本地更改提交远程新分支feature_g

创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

(转)什么是DockerCompose?它有什么作用?

一、什么是DockerCompose? DockerCompose可以基于Compose文件帮我们快速的部署分布式应用&#xff0c;而无需手动一个个创建和运行容器。 Compose文件是一个文本文件&#xff0c;通过指令定义集群中的每个容器如何运行。 DockerCompose就是把DockerFile转换成指令去运行。 …...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

scikit-learn机器学习

# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

Web中间件--tomcat学习

Web中间件–tomcat Java虚拟机详解 什么是JAVA虚拟机 Java虚拟机是一个抽象的计算机&#xff0c;它可以执行Java字节码。Java虚拟机是Java平台的一部分&#xff0c;Java平台由Java语言、Java API和Java虚拟机组成。Java虚拟机的主要作用是将Java字节码转换为机器代码&#x…...

怎么让Comfyui导出的图像不包含工作流信息,

为了数据安全&#xff0c;让Comfyui导出的图像不包含工作流信息&#xff0c;导出的图像就不会拖到comfyui中加载出来工作流。 ComfyUI的目录下node.py 直接移除 pnginfo&#xff08;推荐&#xff09;​​ 在 save_images 方法中&#xff0c;​​删除或注释掉所有与 metadata …...