通过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 的测试运行结果摘要为:
二:获得内存分区间的大小。
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的话读者可以试试,会多一些东西。
在我的测试输出为:
看的还是很清楚的。
三: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(); }
在我的机器测试输出为:
这是运行过一段时间够的结果,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(); }