【监控】通过jmx获得系统的gc,内存情况

通过jmx访问jvm知道的Mbean的一些信息,可以取得系统运行时的一些情况,

比如说,内存(堆内存大小,非堆内存大小),还有各个区的内存大小。

还可以访问gc收集器的gc次数。来确定minorGC和fullGc的次数都可以获得。

 

一:获得堆内存和非堆内存的大小。

 

public String monitorMemory() {

        StringBuilder sb = new StringBuilder("Memory:");

        MemoryMXBean mmbean = ManagementFactory.getMemoryMXBean();
        MemoryUsage hmu = mmbean.getHeapMemoryUsage();
        sb.append("[HeapMemoryUsage:");
        sb.append(" Used=" + formatBytes(hmu.getUsed()));
        sb.append(" Committed=" + formatBytes(hmu.getCommitted()));
        sb.append("]");

        MemoryUsage nhmu = mmbean.getNonHeapMemoryUsage();
        sb.append("[NonHeapMemoryUsage:");
        sb.append(" Used=" + formatBytes(nhmu.getUsed()));
        sb.append(" Committed=" + formatBytes(nhmu.getCommitted()));
        sb.append("]");

        return sb.toString();
    }

 

在我的测试代码下,jdk1.6下 -server 的测试运行结果摘要为:

 

写道
Memory:[HeapMemoryUsage: Used=656K Committed=6016K][NonHeapMemoryUsage: Used=3414K Committed=6400K]
 

 

二:获得内存分区间的大小。

 

public String monitorMemoryPool() {
        StringBuilder sb = new StringBuilder("MemoryPool:");

        List<MemoryPoolMXBean> pools = ManagementFactory.getMemoryPoolMXBeans();

        for (MemoryPoolMXBean p : pools) {
            sb.append("[" + p.getName() + ":");
            MemoryUsage u = p.getUsage();
            sb.append(" Used=" + formatBytes(u.getUsed()));
            sb.append(" Committed=" + formatBytes(u.getCommitted()));
            sb.append("]");

        }
        return sb.toString();

    }

 

这个的输出,跟平添相关性很大,并且跟启动的jvm参数也有关系,我这里是用-server的模式启动,-client的话读者可以试试,会多一些东西。

 

在我的测试输出为:

 

写道
MemoryPool:[Code Cache: Used=354K Committed=2304K][PS Eden Space: Used=410K Committed=768K][PS Survivor Space: Used=0K Committed=128K][PS Old Gen: Used=246K Committed=5120K][PS Perm Gen: Used=3060K Committed=4096K]

 

看的还是很清楚的。

 

三:gc收集器的gc次数。

 

public String monitorGC() {
        StringBuilder sb = new StringBuilder("GC:");

        List<GarbageCollectorMXBean> gcmbeans = ManagementFactory.getGarbageCollectorMXBeans();

        for (GarbageCollectorMXBean gc : gcmbeans) {
            sb.append("[" + gc.getName() + ": ");
            sb.append("Count=" + gc.getCollectionCount());
            sb.append(" GCTime=" + formatMillis(gc.getCollectionTime()));
            sb.append("]");
        }

        return sb.toString();
    }

 

 

在我的机器测试输出为:

 

写道
GC:[PS Scavenge: Count=29 GCTime=0.0460sec][PS MarkSweep: Count=7 GCTime=0.1220sec]

 

这是运行过一段时间够的结果,minorGC和full gc对应的gc方式分别对应上面的2个名字。

因此可以看到,minorGC29次,FULL GC 7次。

 

关于这个可以进一步查看  RednaxelaFX 的 通过Java/JMX得到full GC次数?

 

四:结果。

 

既然能够在运行中动态得到这些数据,那就可以用来进行一些简单的系统监控,启动一个线程,每隔2分钟采一次样,然后进行分析记录。

 

通过剩余内存的大小,一段时间内FULL GC 的次数来进行相应的预警,还是比较简单,有效的。

 

我这使用的测试代码,每隔5秒钟打印一次信息。

 

public static void main(String[] args) {

        System.out.println("beging monitor");

        new Thread(new Runnable() {
            public void run() {
                JmxMonitorUtil monitor = new JmxMonitorUtil();

                while (true) {
                    
                    System.out.println("------------------------");
                    System.out.println(monitor.monitorMemory());
                    System.out.println(monitor.monitorMemoryPool());
                    System.out.println(monitor.monitorGC());
                    System.out.println("------------------------");

                    try {
                        Thread.sleep(5000);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }).start();
        
    }

你可能感兴趣的:(jvm,thread,多线程,cache)