Java JVM 可观测的原理解释和落地方案对比

如何监控 JVM

我们使用 Prometheus 来作为可观测平台的指标监控的核心组件。监控一个云原生的 Java 应用,一般会分成 3 个步骤:

  1. 配置 Java 应用,暴露 JVM 指标信息

  2. 通过 Prometheus 采集并存储指标数据

  3. 通过 Grafana 的 Dashboard 展示采集到的指标

借力社区生态,我们有越来越丰富的方式来暴露 JVM 核心指标,文本将介绍 JVM 监控的基本原理,并重点介绍常见的 3 种暴露 JVM 指标的方案,可以根据读者的使用场景来选择。

采集原理

Java Management Extensions(JMX)技术是 Java SE 平台的标准功能,提供了一种简单的、标准的监控和管理资源的方式,对于如何定义一个资源给出了明确的结构和设计模式,主要用于监控和管理 Java 应用程序运行状态、设备和资源信息、Java 虚拟机运行情况等信息。并且如下图所示,有关应用程序性能和资源使用情况的详细信息可以从 JMX 指标中导出。如果有任何问题,我们可以借助收集的指标进行诊断,并对系统进行微调以获得最佳性能。JMX 是可以动态的,所以也可以在资源创建、安装、实现时进行动态监控和管理,JDK 自带的 jconsole 就是使用 JMX 技术实现的监控工具。图片:

使用 JMX 技术时,通过定义一个被称为 MBean 或 MXBean 的 Java 对象来表示要管理指定的资源,然后可以把资源信息注册到 MBean Server 对外提供服务。MBean Server 充当了对外提供服务和对内管理 MBean 资源的代理功能,如此优雅的设计让 MBean 资源管理和 MBean Server 代理完全独立开,使之可以自由的控制 MBean 资源信息。

JMX 不仅仅用于本地管理,JMX Remote API 为 JMX 添加了远程功能,使之可以通过网络远程监视和管理应用程序。得益于相对独立的架构设计,使 JMX 可以平滑的集成到各种监控系统之中。并具有包括遵守 Java 规范、通用的管理方式、开箱即用的监控功能、架构设计优秀、监测 JVM 状态能力、管理解决方案集成的能力等优点。

JMX 技术架构主要有资源管理(MBean/MXBean)模块,资源代理模块(MBean Server),远程管理模块(Remote API)组成 ,下面的图片来自维基百科,很好的展示了三个模块之间的关系。图片:

资源管理在架构中标识为资源探测层(Probe Level),在 JMX 中, 使用 MBean 或 MXBean 来表示一个资源(下面简称 MBean),访问和管理资源也都是通过 MBean。

JMX 已经对 JVM 进行了多维度资源检测,所以可以轻松启动 JMX 代理来访问内置的 JVM 资源检测,从而通过 JMX 技术远程监控和管理 JVM。JMX 内置了常用的 JVM 资源监测类,包括但不限于:类加载、垃圾收集、日志系统、内存池、内存、内存系统、操作系统、运行时系统和线程系统。

以下代码演示了如何使用原生 JMX 接口获取 JVM 指标:

package org.example.jmx;
import java.lang.management.CompilationMXBean;import java.lang.management.GarbageCollectorMXBean;import java.lang.management.ManagementFactory;import java.lang.management.MemoryMXBean;import java.lang.management.MemoryManagerMXBean;import java.lang.management.MemoryUsage;import java.lang.management.OperatingSystemMXBean;import java.util.Arrays;import java.util.List;import java.util.stream.Collectors;
public class Main {
  
    public static void main(String[] args) {
          printOSInfo();        System.out.println("================");        printMemoryManagerInfo();        System.out.println("================");        printGCInfo();    }
    //通过 OperatingSystemMXBean 获取 OS 信息    public static void printOSInfo() {
          OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();        String osName = operatingSystemMXBean.getName();        String osVersion = operatingSystemMXBean.getVersion();        int processors = operatingSystemMXBean.getAvailableProcessors();        System.out.println(String.format("OS:%s,Version:%s,CPU:%d 个", osName, osVersion, processors));
        CompilationMXBean compilationMXBean = ManagementFactory.getCompilationMXBean();        String compilationMXBeanName = compilationMXBean.getName();        System.out.println("编译系统:" + compilationMXBeanName);
        MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();        MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();        long max = heapMemoryUsage.getMax();        long used = heapMemoryUsage.getUsed();        System.out.println(String.format("使用内存:%dMB/%dMB", used / 1024 / 1024, max / 1024 / 1024));
        List<GarbageCollectorMXBean> gcMXBeans = ManagementFactory.getGarbageCollectorMXBeans();        String gcNames = gcMXBeans.stream()                                  .map(MemoryManagerMXBean::getName)                                  .collect(Collectors.joining(","));        System.out.println("垃圾收集器:" + gcNames);    }
    // 通过 MemoryManagerMXBean 获取 JVM 内存管理器信息    public static void printMemoryManagerInfo() {
          List<MemoryManagerMXBean> managers = ManagementFactory.getMemoryManagerMXBeans();        if (managers != null && !managers.isEmpty()) {
              for (MemoryManagerMXBean manager : managers) {
                  System.out.println("vm内存管理器:名称=" + manager.getName() + ",管理的内存区="                                       + Arrays.deepToString(                    manager.getMemoryPoolNames()) + ",ObjectName=" + manager.getObjectName());            }        }    }
    //通过 GarbageCollectorMXBean 获取 JVM GC 信息    public static void printGCInfo() {
          try {
              List<GarbageCollectorMXBean> gcMxBeans = ManagementFactory.getGarbageCollectorMXBeans();
            for (GarbageCollectorMXBean gcMxBean : gcMxBeans) {
                  System.out.println(gcMxBean.getName());                System.out.println(gcMxBean.getObjectName());            }
        } catch (RuntimeException re) {
              throw re;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java虚拟机(JVM)是Java程序的运行环境,负责将编写好的Java代码转换为可执行的机器指令。了解和优化JVM原理对于开发高效的Java应用程序至关重要。 首先,JVM内存管理是优化的关键。JVM将内存分为堆和栈两部分。堆用于存储对象实例,而栈用于存储方法调用过程中的局部变量和操作数。合理地管理堆和栈的大小,以及使用垃圾回收机制清理不再使用的对象,可以减少内存泄漏和提高程序性能。 其次,JIT编译器是JVM的重要组成部分,能够将频繁执行的热点代码编译成本地机器码。了解JIT编译器的工作原理,可以通过合理的代码结构和编写高效的算法,提高Java程序的执行速度。 此外,调优JVM的参数也是优化Java性能的重要手段。例如,可以调整堆和栈的大小,调整垃圾回收器的选项,以及选择适当的垃圾回收算法。通过合理地调整这些参数,可以在程序运行时获得更好的性能和稳定性。 还有一些常用的JVM工具,如JProfiler和VisualVM,可以对Java应用程序的性能进行分析和优化。了解和使用这些工具,可以更准确地定位性能瓶颈,进一步优化程序的性能。 总而言之,对于Java开发人员来说,了解JVM原理和有优化经验是非常重要的。只有深入理解JVM内部的工作原理,才能更好地编写高效的Java程序,提高应用程序的性能和可靠性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值