zoukankan      html  css  js  c++  java
  • 如何通过代码监控JVM的运行状态

    一、背景

    工作中我们需要对自己负责的系统的运行状态进行监控,这个通常会使用公司内部的监控系统。我本来是没想太多的,但有次无意中了解到公司对于GC次数时间的监控居然是自己写程序解析JVM的gc日志,这让我有点大吃一惊,我虽然知道JVM对外提供了接口获取各种信息,但当时又一下子想不起来叫什么名字,怎么用,于是决定总结一下这块东西,写个Demo记下来便于以后使用是查看。

    二、解决方案

    其实要获取JVM运行时的各项指标非常简单,只需要调用JVM提供的接口进行获取就好,核心类名叫做ManagementFactory,下面一一介绍一下。

    1.JVM启动参数

    System.out.println("===============程序运行参数==================");
    RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();
    //JVM启动参数
    System.out.println(runtimeMXBean.getInputArguments());
    //系统属性
    System.out.println(runtimeMXBean.getSystemProperties());
    //JVM名字
    System.out.println(runtimeMXBean.getVmName());
    

    2.线程状态

    System.out.println("===============线程状态=======================");
    ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
    //获取当前JVM内的线程数量,该指标非常重要。
    //之前遇到过用为没有对该指标进行监控而导致问题无法及时定位的情况。
    System.out.println(threadMXBean.getThreadCount());
    System.out.println(threadMXBean.getCurrentThreadCpuTime());
    System.out.println(threadMXBean.getCurrentThreadUserTime());
    

    3.类加载情况

    System.out.println("===============类加载状态============================");
    ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
    //获取当前JVM加载的类数量
    System.out.println(classLoadingMXBean.getLoadedClassCount());
    //获取JVM总加载的类数量
    System.out.println(classLoadingMXBean.getTotalLoadedClassCount());
    //获取JVM卸载的类数量
    System.out.println(classLoadingMXBean.getUnloadedClassCount());
    

    4.系统状态

    System.out.println("================系统状态======================");
    OperatingSystemMXBean operatingSystemMXBean = ManagementFactory.getOperatingSystemMXBean();
    //获取服务器的CPU个数
    System.out.println(operatingSystemMXBean.getAvailableProcessors());
    //获取服务器的平均负载。这个指标非常重要,它可以有效的说明当前机器的性能是否正常,如果load过高,说明CPU无法及时处理任务。
    System.out.println(operatingSystemMXBean.getSystemLoadAverage());
    

    5.总内存内存使用状态

    System.out.println("================内存状态===========================");
    MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
    //获取堆内存使用情况,包括初始大小,最大大小,已使用大小等,单位字节
    System.out.println(memoryMXBean.getHeapMemoryUsage().toString());
    //获取堆外内存使用情况。
    System.out.println(memoryMXBean.getNonHeapMemoryUsage().toString());
    

    6.各个内存区使用状态

    System.out.println("================堆内存状态======================");
    //这里会返回老年代,新生代等内存区的使用情况,按需自取就好
    List<MemoryPoolMXBean> memoryPoolMXBeans = ManagementFactory.getMemoryPoolMXBeans();
    memoryPoolMXBeans.forEach((pool) -> {
        System.out.println(pool.getName());
        System.out.println(pool.getUsage());
    });
    
    输出结果:
    ================堆内存状态======================
    Code Cache
    init = 2555904(2496K) used = 1497216(1462K) committed = 2555904(2496K) max = 251658240(245760K)
    Metaspace
    init = 0(0K) used = 4513312(4407K) committed = 5111808(4992K) max = -1(-1K)
    Compressed Class Space
    init = 0(0K) used = 513592(501K) committed = 655360(640K) max = 1073741824(1048576K)
    PS Eden Space
    init = 8388608(8192K) used = 4191808(4093K) committed = 8388608(8192K) max = 8388608(8192K)
    PS Survivor Space
    init = 1048576(1024K) used = 0(0K) committed = 1048576(1024K) max = 1048576(1024K)
    PS Old Gen
    init = 10485760(10240K) used = 0(0K) committed = 10485760(10240K) max = 20971520(20480K)
    

    6.GC状态
    JVM启动参数:-server -Xmx30m -Xms20m -Xmn10m -XX:+UseParNewGC
    -XX:+UseConcMarkSweepGC

    System.out.println("===============GC状态==========================");
    List<GarbageCollectorMXBean> garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
    garbageCollectorMXBeans.forEach(collector -> {
         System.out.println(collector.getName());
         System.out.println(collector.getCollectionCount());
         System.out.println(collector.getCollectionTime());
    });
    
    输出结果:
    ===============GC状态==========================
    ParNew
    12
    24
    ConcurrentMarkSweep
    24
    225
    

    三、总结

    有了这些基础数据以后就可以监控我们的系统运行状态,比如说起一个daemon线程,每秒中统计一下数据,有问题就报警。分布式系统的话可以定时上报系统的运行状态然后再进行汇总监控。



    作者:凌风郎少
    链接:https://www.jianshu.com/p/978522f88ad0
    來源:简书
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
  • 相关阅读:
    MySQL
    php抽象类和接口
    php面向对象三大特征
    php面向对象
    Git
    css3属性
    数据渲染
    ajax(2)
    ajax笔记
    作用域面试题
  • 原文地址:https://www.cnblogs.com/albertzhangyu/p/9787804.html
Copyright © 2011-2022 走看看