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() ']';
}
}