使用 java.lang.management 包监控 java 虚拟机

2022-06-27 12:28:58 浏览数 (1)

1. 概述

对 java 来说,jvm 的监控是工程应用中十分重要的一环,无论是日常的性能优化还是异常处理都离不开监控数据的分析。 java 的 java.lang.management 包提供了用于监控和管理 java 虚拟机及虚拟机各项指标的接口。

2. java.lang.management 提供的接口

java.lang.management 提供了下列接口。

java.lang.management 提供的接口

接口

用途

ClassLoadingMXBean

用于 Java 虚拟机的类加载系统的管理接口

CompilationMXBean

用于 Java 虚拟机的编译系统的管理接口

GarbageCollectorMXBean

用于 Java 虚拟机的垃圾回收的管理接口

MemoryManagerMXBean

内存管理器的管理接口

MemoryMXBean

Java 虚拟机的内存系统的管理接口

MemoryPoolMXBean

内存池的管理接口

OperatingSystemMXBean

用于操作系统的管理接口,Java 虚拟机在此操作系统上运行

RuntimeMXBean

Java 虚拟机的运行时系统的管理接口

ThreadMXBean

Java 虚拟机线程系统的管理接口

3. 应用实例

代码语言:javascript复制
import java.lang.management.ClassLoadingMXBean;
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.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.lang.management.RuntimeMXBean;
import java.lang.management.ThreadMXBean;
import java.util.List;

import javax.management.MBeanServerConnection;

public class MBeanDemo {

    public static void main(String[] args) {
        showJvmInfo();
        showMemoryInfo();
        showSystem();
        showClassLoading();
        showCompilation();
        showThread();
        showGarbageCollector();
        showMemoryManager();
        showMemoryPool();
    }

    /**
     * Java 虚拟机的运行时系统
     */
    public static void showJvmInfo() {
        RuntimeMXBean mxbean = ManagementFactory.getRuntimeMXBean();
        String vendor = mxbean.getVmVendor();
        System.out.println("jvm name:"   mxbean.getVmName());
        System.out.println("jvm version:"   mxbean.getVmVersion());
        System.out.println("jvm bootClassPath:"   mxbean.getBootClassPath());
        System.out.println("jvm start time:"   mxbean.getStartTime());
    }

    /**
     * Java 虚拟机的内存系统
     */
    public static void showMemoryInfo() {
        MemoryMXBean mem = ManagementFactory.getMemoryMXBean();
        MemoryUsage heap = mem.getHeapMemoryUsage();
        System.out.println("Heap committed:"   heap.getCommitted()   " init:"   heap.getInit()   " max:"
                  heap.getMax()   " used:"   heap.getUsed());
    }

    /**
     * Java 虚拟机在其上运行的操作系统
     */
    public static void showSystem() {
        OperatingSystemMXBean op = ManagementFactory.getOperatingSystemMXBean();
        System.out.println("Architecture: "   op.getArch());
        System.out.println("Processors: "   op.getAvailableProcessors());
        System.out.println("System name: "   op.getName());
        System.out.println("System version: "   op.getVersion());
        System.out.println("Last minute load: "   op.getSystemLoadAverage());
    }

    /**
     * Java 虚拟机的类加载系统
     */
    public static void showClassLoading(){
        ClassLoadingMXBean cl = ManagementFactory.getClassLoadingMXBean();
        System.out.println("TotalLoadedClassCount: "   cl.getTotalLoadedClassCount());
        System.out.println("LoadedClassCount"   cl.getLoadedClassCount());
        System.out.println("UnloadedClassCount:"   cl.getUnloadedClassCount());
    }

    /**
     * Java 虚拟机的编译系统
     */
    public static void showCompilation(){
        CompilationMXBean com = ManagementFactory.getCompilationMXBean();
        System.out.println("TotalCompilationTime:"   com.getTotalCompilationTime());
        System.out.println("name:"   com.getName());
    }

    /**
     * Java 虚拟机的线程系统
     */
    public static void showThread(){
        ThreadMXBean thread = ManagementFactory.getThreadMXBean();
        System.out.println("ThreadCount"   thread.getThreadCount());
        System.out.println("AllThreadIds:"   thread.getAllThreadIds());
        System.out.println("CurrentThreadUserTime"   thread.getCurrentThreadUserTime());
        //......还有其他很多信息
    }

    /**
     * Java 虚拟机中的垃圾回收器。
     */
    public static void showGarbageCollector(){
        List<GarbageCollectorMXBean> gc = ManagementFactory.getGarbageCollectorMXBeans();
        HashSet younggcAlgorithm = new HashSet() {
            {
                this.add("Copy");
                this.add("ParNew");
                this.add("PS Scavenge");
            }
        };
        HashSet oldgcAlgorithm = new HashSet() {
            {
                this.add("MarkSweepCompact");
                this.add("PS MarkSweep");
                this.add("ConcurrentMarkSweep");
            }
        };
        for(GarbageCollectorMXBean GarbageCollectorMXBean : gc){
            String gcAlgorithm = GarbageCollectorMXBean.getName();
            System.out.println("name:"   gcAlgorithm);
            System.out.println("CollectionCount:"   GarbageCollectorMXBean.getCollectionCount());
            System.out.println("CollectionTime"   GarbageCollectorMXBean.getCollectionTime());
            if(younggcAlgorithm.contains(gcAlgorithm)) {
                System.out.println("YoungGCCount:"   GarbageCollectorMXBean.getCollectionCount());
                System.out.println("YoungGCTime"   GarbageCollectorMXBean.getCollectionTime());
            } else if(oldgcAlgorithm.contains(gcAlgorithm)) {
                System.out.println("FullGCCount:"   GarbageCollectorMXBean.getCollectionCount());
                System.out.println("FullGCTime"   GarbageCollectorMXBean.getCollectionTime());
            }
        }
    }

    /**
     * Java 虚拟机中的内存管理器
     */
    public static void showMemoryManager(){
        List<MemoryManagerMXBean> mm = ManagementFactory.getMemoryManagerMXBeans();
        for(MemoryManagerMXBean eachmm: mm){
            System.out.println("name:"   eachmm.getName());
            System.out.println("MemoryPoolNames:"   eachmm.getMemoryPoolNames().toString());
        }
    }

    /**
     * Java 虚拟机中的内存池
     */
    public static void showMemoryPool(){
        List<MemoryPoolMXBean> mps = ManagementFactory.getMemoryPoolMXBeans();
        for(MemoryPoolMXBean mp : mps){
            System.out.println("name:"   mp.getName());
            System.out.println("CollectionUsage:"   mp.getCollectionUsage());
            System.out.println("type:"   mp.getType());
        }
    }

    /**
     * 访问 MXBean 的方法的三种方法
     */
    public static void visitMBean(){

        // 第一种直接调用同一 Java 虚拟机内的 MXBean 中的方法。
        RuntimeMXBean mxbean = ManagementFactory.getRuntimeMXBean();
        String vendor1 = mxbean.getVmVendor();
        System.out.println("vendor1:"   vendor1);

        /* 第二种通过一个连接到正在运行的虚拟机的平台 MBeanServer 的 MBeanServerConnection。
        MBeanServerConnection mbs = null;
        // Connect to a running JVM (or itself) and get MBeanServerConnection
        // that has the JVM MXBeans registered in it

        try {
            // Assuming the RuntimeMXBean has been registered in mbs
            ObjectName oname = new ObjectName(ManagementFactory.RUNTIME_MXBEAN_NAME);
            String vendor2 = (String) mbs.getAttribute(oname, "VmVendor");
            System.out.println("vendor2:"   vendor2);
        } catch (Exception e) {
            e.printStackTrace();
        }
        */

        /* 第三种使用 MXBean 代理
        MBeanServerConnection mbs3 = null;
        RuntimeMXBean proxy;
        try {
            proxy = ManagementFactory.newPlatformMXBeanProxy(mbs3,ManagementFactory.RUNTIME_MXBEAN_NAME,
                                                     RuntimeMXBean.class);
            String vendor = proxy.getVmVendor();
        } catch (IOException e) {
            e.printStackTrace();
        }
        */
    }
}

4. 获取内存大小

下面的类实现了 jvm 内存各项指标的获取:

代码语言:javascript复制
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.OperatingSystemMXBean;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.Iterator;
import java.util.Locale;
import javax.management.MBeanServer;

public class MemoryInformations {
    private static final String NEXT = ",n";
    private static final String MO = " Mo";
    private final long usedMemory = Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
    private final long maxMemory = Runtime.getRuntime().maxMemory();
    private final long usedOldGen;
    private final long maxOldGen;
    private final long usedPermGen;
    private final long maxPermGen;
    private final long usedEdenSpace;
    private final long maxEdenSpace;
    private final long usedSurvivorSpace;
    private final long maxSurvivorSpace;
    private final long usedNonHeapMemory;
    private final long maxNonHeapMemory;
    private final int loadedClassesCount;
    private final long garbageCollectionTimeMillis;
    private final long usedPhysicalMemorySize;
    private final long usedSwapSpaceSize;
    private final String memoryDetails;
    private static MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();

    MemoryInformations() {
        MemoryPoolMXBean permGenMemoryPool = getPermGenMemoryPool();
        if(permGenMemoryPool != null) {
            MemoryUsage oldGenMemoryPool = permGenMemoryPool.getUsage();
            this.usedPermGen = oldGenMemoryPool.getUsed();
            this.maxPermGen = oldGenMemoryPool.getMax();
        } else {
            this.usedPermGen = 0L;
            this.maxPermGen = 0L;
        }

        MemoryPoolMXBean oldGenMemoryPool1 = getOldGenMemoryPool();
        if(oldGenMemoryPool1 != null) {
            MemoryUsage edenSpaceMemoryPool = oldGenMemoryPool1.getUsage();
            this.usedOldGen = edenSpaceMemoryPool.getUsed();
            this.maxOldGen = edenSpaceMemoryPool.getMax();
        } else {
            this.usedOldGen = 0L;
            this.maxOldGen = 0L;
        }

        MemoryPoolMXBean edenSpaceMemoryPool1 = getEdenSpacePool();
        if(edenSpaceMemoryPool1 != null) {
            MemoryUsage survivorSpacePool = edenSpaceMemoryPool1.getUsage();
            this.usedEdenSpace = survivorSpacePool.getUsed();
            this.maxEdenSpace = survivorSpacePool.getMax();
        } else {
            this.usedEdenSpace = 0L;
            this.maxEdenSpace = 0L;
        }

        MemoryPoolMXBean survivorSpacePool1 = getSurvivorSpaceMemoryPool();
        if(survivorSpacePool1 != null) {
            MemoryUsage operatingSystem = survivorSpacePool1.getUsage();
            this.usedSurvivorSpace = operatingSystem.getUsed();
            this.maxSurvivorSpace = operatingSystem.getMax();
        } else {
            this.usedSurvivorSpace = 0L;
            this.maxSurvivorSpace = 0L;
        }

        this.usedNonHeapMemory = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getUsed();
        this.maxNonHeapMemory = ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage().getMax();
        this.loadedClassesCount = ManagementFactory.getClassLoadingMXBean().getLoadedClassCount();
        this.garbageCollectionTimeMillis = buildGarbageCollectionTimeMillis();
        OperatingSystemMXBean operatingSystem1 = ManagementFactory.getOperatingSystemMXBean();
        if(isSunOsMBean(operatingSystem1)) {
            com.sun.management.OperatingSystemMXBean osBean = (com.sun.management.OperatingSystemMXBean)operatingSystem1;
            this.usedPhysicalMemorySize = osBean.getTotalPhysicalMemorySize() - osBean.getFreePhysicalMemorySize();
            this.usedSwapSpaceSize = osBean.getTotalSwapSpaceSize() - osBean.getFreeSwapSpaceSize();
        } else {
            this.usedPhysicalMemorySize = 0L;
            this.usedSwapSpaceSize = 0L;
        }

        this.memoryDetails = this.buildMemoryDetails();
    }

    private static MemoryPoolMXBean getPermGenMemoryPool() {
        Iterator var0 = ManagementFactory.getMemoryPoolMXBeans().iterator();

        MemoryPoolMXBean memoryPool;
        do {
            if(!var0.hasNext()) {
                return null;
            }

            memoryPool = (MemoryPoolMXBean)var0.next();
        } while(!memoryPool.getName().endsWith("Perm Gen"));

        return memoryPool;
    }

    private static MemoryPoolMXBean getOldGenMemoryPool() {
        Iterator var0 = ManagementFactory.getMemoryPoolMXBeans().iterator();

        MemoryPoolMXBean memoryPool;
        do {
            if(!var0.hasNext()) {
                return null;
            }

            memoryPool = (MemoryPoolMXBean)var0.next();
        } while(!memoryPool.getName().endsWith("Old Gen"));

        return memoryPool;
    }

    private static MemoryPoolMXBean getEdenSpacePool() {
        Iterator var0 = ManagementFactory.getMemoryPoolMXBeans().iterator();

        MemoryPoolMXBean memoryPool;
        do {
            if(!var0.hasNext()) {
                return null;
            }

            memoryPool = (MemoryPoolMXBean)var0.next();
        } while(!memoryPool.getName().endsWith("Eden Space"));

        return memoryPool;
    }

    private static MemoryPoolMXBean getSurvivorSpaceMemoryPool() {
        Iterator var0 = ManagementFactory.getMemoryPoolMXBeans().iterator();

        MemoryPoolMXBean memoryPool;
        do {
            if(!var0.hasNext()) {
                return null;
            }

            memoryPool = (MemoryPoolMXBean)var0.next();
        } while(!memoryPool.getName().endsWith("Survivor Space"));

        return memoryPool;
    }

    private static long buildGarbageCollectionTimeMillis() {
        long garbageCollectionTime = 0L;

        GarbageCollectorMXBean garbageCollector;
        for(Iterator var2 = ManagementFactory.getGarbageCollectorMXBeans().iterator(); var2.hasNext(); garbageCollectionTime  = garbageCollector.getCollectionTime()) {
            garbageCollector = (GarbageCollectorMXBean)var2.next();
        }

        return garbageCollectionTime;
    }

    private String buildMemoryDetails() {
        DecimalFormat integerFormat = new DecimalFormat("#,##0", DecimalFormatSymbols.getInstance(Locale.getDefault()));
        String nonHeapMemory = "Non heap memory = "   integerFormat.format(this.usedNonHeapMemory / 1024L / 1024L)   " Mo"   " (Perm Gen, Code Cache)";
        String classLoading = "Loaded classes = "   integerFormat.format((long)this.loadedClassesCount);
        String gc = "Garbage collection time = "   integerFormat.format(this.garbageCollectionTimeMillis)   " ms";
        OperatingSystemMXBean operatingSystem = ManagementFactory.getOperatingSystemMXBean();
        String osInfo = "";
        if(isSunOsMBean(operatingSystem)) {
            com.sun.management.OperatingSystemMXBean osBean = (com.sun.management.OperatingSystemMXBean)operatingSystem;
            osInfo = "Process cpu time = "   integerFormat.format(osBean.getProcessCpuTime() / 1000000L)   " ms,nCommitted virtual memory = "   integerFormat.format(osBean.getCommittedVirtualMemorySize() / 1024L / 1024L)   " Mo"   ",nFree physical memory = "   integerFormat.format(osBean.getFreePhysicalMemorySize() / 1024L / 1024L)   " Mo"   ",nTotal physical memory = "   integerFormat.format(osBean.getTotalPhysicalMemorySize() / 1024L / 1024L)   " Mo"   ",nFree swap space = "   integerFormat.format(osBean.getFreeSwapSpaceSize() / 1024L / 1024L)   " Mo"   ",nTotal swap space = "   integerFormat.format(osBean.getTotalSwapSpaceSize() / 1024L / 1024L)   " Mo";
        }

        return nonHeapMemory   ",n"   classLoading   ",n"   gc   ",n"   osInfo;
    }

    private static boolean isSunOsMBean(OperatingSystemMXBean operatingSystem) {
        String className = operatingSystem.getClass().getName();
        return "com.sun.management.OperatingSystem".equals(className) || "com.sun.management.UnixOperatingSystem".equals(className);
    }

    public long getUsedMemory() {
        return this.usedMemory;
    }

    public long getMaxMemory() {
        return this.maxMemory;
    }

    public double getUsedMemoryPercentage() {
        return 100.0D * (double)this.usedMemory / (double)this.maxMemory;
    }

    public long getUsedPermGen() {
        return this.usedPermGen;
    }

    public long getMaxPermGen() {
        return this.maxPermGen;
    }

    public double getUsedPermGenPercentage() {
        return this.usedPermGen > 0L && this.maxPermGen > 0L?100.0D * (double)this.usedPermGen / (double)this.maxPermGen:0.0D;
    }

    public long getUsedOldGen() {
        return this.usedOldGen;
    }

    public long getMaxOldGen() {
        return this.maxOldGen;
    }

    public double getUsedOldGenPercentage() {
        return this.usedOldGen > 0L && this.maxOldGen > 0L?100.0D * (double)this.usedOldGen / (double)this.maxOldGen:0.0D;
    }

    public long getUsedEdenSpace() {
        return this.usedEdenSpace;
    }

    public long getMaxEdenSpace() {
        return this.maxEdenSpace;
    }

    public double getUsedEdenSpacePercentage() {
        return this.usedEdenSpace > 0L && this.maxEdenSpace > 0L?100.0D * (double)this.usedEdenSpace / (double)this.maxEdenSpace:0.0D;
    }

    public long getUsedSurvivorSpace() {
        return this.usedSurvivorSpace;
    }

    public long getMaxSurvivorSpace() {
        return this.maxSurvivorSpace;
    }

    public double getUsedSurvivorSpacePercentage() {
        return this.usedSurvivorSpace > 0L && this.maxSurvivorSpace > 0L?100.0D * (double)this.usedSurvivorSpace / (double)this.maxSurvivorSpace:0.0D;
    }

    public long getUsedDirectBufferSize() {
        long directBufferSize = 0L;

        try {
            ObjectName e = new ObjectName("java.nio:type=BufferPool,name=direct");
            directBufferSize = ((Long)mbeanServer.getAttribute(e, "MemoryUsed")).longValue();
        } catch (Exception var3) {
            LOGGER.warn("get direct buffer size exception.", var3);
        }

        return directBufferSize;
    }

    public long getUsedMappedSize() {
        long mappedBufferSize = 0L;

        try {
            ObjectName e = new ObjectName("java.nio:type=BufferPool,name=mapped");
            mappedBufferSize = ((Long)mbeanServer.getAttribute(e, "MemoryUsed")).longValue();
        } catch (Exception var3) {
            LOGGER.warn("get mapped buffer size exception.", var3);
        }

        return mappedBufferSize;
    }

    public long getUsedNonHeapMemory() {
        return this.usedNonHeapMemory;
    }

    public long getMaxNonHeapMemory() {
        return this.maxNonHeapMemory;
    }

    public double getUsedNonHeapPercentage() {
        return this.usedNonHeapMemory > 0L && this.maxNonHeapMemory > 0L?100.0D * (double)this.usedNonHeapMemory / (double)this.maxNonHeapMemory:0.0D;
    }

    public int getLoadedClassesCount() {
        return this.loadedClassesCount;
    }

    public long getGarbageCollectionTimeMillis() {
        return this.garbageCollectionTimeMillis;
    }

    public long getUsedPhysicalMemorySize() {
        return this.usedPhysicalMemorySize;
    }

    public long getUsedSwapSpaceSize() {
        return this.usedSwapSpaceSize;
    }

    public String getMemoryDetails() {
        return this.memoryDetails;
    }

    public String toString() {
        return this.getClass().getSimpleName()   "[usedMemory="   this.getUsedMemory()   ", maxMemroy="   this.getMaxMemory()   ']';
    }
}

0 人点赞