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 性能监控工具之可视化篇

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/949495.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一款好用的书签管理工具

多平台同步&#xff1a;可以在网页端、手机&#xff08;iOS 和 Android&#xff09;端同步使用。无论你是在电脑上浏览网页添加书签&#xff0c;还是在外出时使用手机&#xff0c;都能方便地访问和管理书签。例如&#xff0c;你在办公室电脑上收藏了一篇关于行业研究的网页&…

ansible-api分析(Inventory)

一. 简述&#xff1a; 通过ansible 实现系统初始化功能&#xff0c; 为和平台嵌入&#xff0c; 需要通过ansible的api进行功能实现。 准确来说&#xff0c;ansible并没有纯粹的外部接入api功能&#xff0c; 只是官方提供了原生类&#xff0c;用于继承接入&#xff0c;从而实现a…

智元机器人千台量产,开启具身智能新纪元

近日&#xff0c;智元机器人正式官宣一则重磅消息&#xff1a;其第 1000 台通用具身机器人成功下线&#xff0c;这无疑在科技领域投下了一颗震撼弹&#xff0c;引发行业内外的广泛关注。 这千台下线的机器人中&#xff0c;涵盖 731 台双足人形机器人&#xff0c;如远征 A2、灵…

ROS2 跨机话题通信问题(同一个校园网账号)

文章目录 写在前面的话校园网模式&#xff08;失败&#xff09;手机热点模式&#xff08;成功&#xff09; 我的实验细节实验验证1、ssh 用户名IP地址 终端控制2、互相 ping 通 IP3、ros2 run turtlesim turtlesim_node/turtle_teleop_key4、ros2 multicast send/receive5、从机…

SUB输入5V升压充电16.8V芯片HU5912

HU5912芯片&#xff0c;作为航誉微电子有限公司推出的一款高性能升压充电管理IC&#xff0c;自其面世以来&#xff0c;便以其出色的性能和广泛的应用领域&#xff0c;受到了业界的高度关注和赞誉。本文将详细介绍HU5912芯片的技术特点、应用优势、市场定位以及其在各类电子设备…

导出中心设计

业务背景 应用业务经常需要导出数据&#xff0c;但是并发的导出以及不合理的导出参数常常导致应用服务的内存溢出、其他依赖应用的崩溃、导出失败&#xff1b;因此才有导出中心的设计 设计思想 将导出应用所需的内存转移至导出中心&#xff0c;将导出的条数加以限制&#xf…

构建智能企业:中关村科金大模型企业知识库的技术解析与应用

在数字化转型的浪潮中&#xff0c;企业对智能化知识管理的需求日益增长。知识作为企业的核心资产&#xff0c;其高效管理和应用对于提升企业运营效率和决策质量至关重要。中关村科金大模型企业知识库凭借其强大的技术架构和广泛的应用场景&#xff0c;成为构建智能企业的重要工…

多线程访问FFmpegFrameGrabber.start方法阻塞问题

一、背景 项目集成网络摄像头实现直播功能需要用到ffmpeg处理rtmp视频流进行web端播放 通过网上资源找到大神的springboot项目实现了rtmp视频流转为http请求进行视频中转功能&#xff0c;其底层利用javacv的FFmpegFrameGrabber进行拉流、推流&#xff0c;进而实现了视频中转。 …

C++11——2:可变模板参数

一.前言 C11引入了可变模板参数&#xff08;variadic template parameters&#xff09;的概念&#xff0c;它允许我们在模板定义中使用可变数量的参数。这样&#xff0c;我们就可以处理任意数量的参数&#xff0c;而不仅限于固定数量的参数。 二.可变模板参数 我们早在C语言…

ENSP综合实验(中小型网络)

一、实验背景 在当今数字化的企业环境中&#xff0c;一个稳定、高效且安全的网络架构对于业务的持续运营和发展至关重要。随着企业内部各部门业务的不断拓展&#xff0c;如财务部门对数据保密性要求极高&#xff0c;访客区域的网络接入需求逐渐增多&#xff0c;以及对外提供特定…

nvidia控制面板找不到怎么回事?这有解决方法!

NVIDIA控制面板是一款用于管理和调整NVIDIA显卡的软件&#xff0c;它可以让你优化游戏和图形应用程序的性能和画质&#xff0c;以及设置多显示器、音视频、CUDA等功能。但是&#xff0c;有时候你可能会发现你的电脑上找不到NVIDIA控制面板&#xff0c;这可能是由于以下原因造成…

在Vue3项目中使用svg-sprite-loader

1.普通的svg图片使用方式 1.1 路径引入 正常我们会把项目中的静态资源放在指定的一个目录&#xff0c;例如assets,使用起来就像 <img src"../assets/svgicons/about.svg" /> 1.2封装组件使用 显然上面的这种方法在项目开发中不太适用&#xff0c;每次都需…

html+css+js网页设计 美食 美食3个页面(带js)

htmlcssjs网页设计 美食 美食3个页面(带js) 网页作品代码简单&#xff0c;可使用任意HTML辑软件&#xff08;如&#xff1a;Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作&#xff09;。 获取源码 1&…

【235. 二叉搜索树的最近公共祖先 中等】

题目&#xff1a; 给定一个二叉搜索树, 找到该树中两个指定节点的最近公共祖先。 百度百科中最近公共祖先的定义为&#xff1a;“对于有根树 T 的两个结点 p、q&#xff0c;最近公共祖先表示为一个结点 x&#xff0c;满足 x 是 p、q 的祖先且 x 的深度尽可能大&#xff08;一…

Visual Studio C++使用笔记

个人学习笔记 右侧项目不显示 CTRL ALT L 创建第一个项目 添加类&#xff08;头文件、CPP文件&#xff09;

【Shell脚本】Docker构建Java项目,并自动停止原镜像容器,发布新版本

本文简述 经常使用docker部署SpringBoot 项目&#xff0c;因为自己的服务器小且项目简单&#xff0c;因此没有使用自动化部署。每次将jar包传到服务器后&#xff0c;需要手动构建&#xff0c;然后停止原有容器&#xff0c;并使用新的镜像启动&#xff0c;介于AI时代越来越懒的…

vulhubn中potato靶场

IP和端口探测 80端口是一个图片 7120端口是这个 使用 hydra爆破密码 使用ssh远程登录 执行exp提权到root成功&#xff0c;找到Flag&#xff01;

复杂园区网基本分支的构建

目录 1、各主机进行网络配置。2、交换机配置。3、配置路由交换&#xff0c;进行测试。4、配置路由器接口和静态路由&#xff0c;进行测试。5、最后测试任意两台主机通信情况 模拟环境链接 拓扑结构 说明&#xff1a; VLAN标签在上面的一定是GigabitEthernet接口的&#xff0c…

信息科技伦理与道德2:研究方法

1 问题描述 1.1 讨论&#xff1f; 请挑一项信息技术&#xff0c;谈一谈为什么认为他是道德的/不道德的&#xff0c;或者根据使用场景才能判断是否道德。判断的依据是什么&#xff08;自身的道德准则&#xff09;&#xff1f;为什么你觉得你的道德准则是合理的&#xff0c;其他…

git理解记录

文章目录 1. 背景2. 基本概念3. 日常工作流程4. 其他常见操作4.1 merge合并操作4.2 tag打标签操作4.3 remoute远程操作4.4 撤销修改 git理解记录 1. 背景 git作为分布式版本控制系统&#xff0c;开源且免费&#xff0c;相比svn集中式版本控制系统存在速度快(HEAD指针指向某次co…