JMX 提供的虚拟机检测 API

检测虚拟机当前的状态总是 Java 开放人员所关心的,也正是因为如此,出现了大量的 profiler 工具来检测当前的虚拟机状态。从 Java SE 5 之后,在 JDK 中,我们有了一些 Java 的虚拟机检测 API,即 java.lang.management包。 Management 包里面包括了许多 MXBean 的接口类和 LockInfo、MemoryUsage、MonitorInfo 和 ThreadInfo 等类。从名字可以看出,该包提供了虚拟机内存分配、垃圾收集(GC)情况、操作系统层、线程调度和共享锁,甚至编译情况的检测机制。这样一来,Java 的开发人员就可以很简单地为自己做一些轻量级的系统检测,来确定当前程序的各种状态,以便随时调整。

要获得这些信息,我们首先通过 java.lang.management.ManagementFactory这个工厂类来获得一系列的 MXBean。包括:

  • ClassLoadingMXBean

    ClassLoadMXBean 包括一些类的装载信息,比如有多少类已经装载 / 卸载(unloaded),虚拟机类装载的 verbose 选项(即命令行中的 Java – verbose:class 选项)是否打开,还可以帮助用户打开 / 关闭该选项。

  • CompilationMXBean

    CompilationMXBean 帮助用户了解当前的编译器和编译情况,该 mxbean 提供的信息不多。

  • GarbageCollectorMXBean

    相 对于开放人员对 GC 的关注程度来说,该 mxbean 提供的信息十分有限,仅仅提供了 GC 的次数和 GC 花费总时间的近似值。但是这个包中还提供了三个的内存管理检测类:MemoryManagerMXBean,MemoryMXBean 和 MemoryPoolMXBean。

    • MemoryManagerMXBean

      这个类相对简单,提供了内存管理类和内存池(memory pool)的名字信息。

    • MemoryMXBean

      这个类提供了整个虚拟机中内存的使用情况,包括 Java 堆(heap)和非 Java 堆所占用的内存,提供当前等待 finalize 的对象数量,它甚至可以做 gc(实际上是调用 System.gc)。

    • MemoryPoolMXBean

      该 信息提供了大量的信息。在 JVM 中,可能有几个内存池,因此有对应的内存池信息,因此,在工厂类中,getMemoryPoolMXBean() 得到是一个 MemoryPoolMXBean 的 list。每一个 MemoryPoolMXBean 都包含了该内存池的详细信息,如是否可用、当前已使用内存 / 最大使用内存值、以及设置最大内存值等等。

  • OperatingSystemMXBean

    该类提供的是操作系统的简单信息,如构架名称、当前 CPU 数、最近系统负载等。

  • RuntimeMXBean

    运行时信息包括当前虚拟机的名称、提供商、版本号,以及 classpath、bootclasspath 和系统参数等等。

  • ThreadMXBean

    在 Java 这个多线程的系统中,对线程的监控是相当重要的。ThreadMXBean 就是起到这个作用。ThreadMXBean 可以提供的信息包括各个线程的各种状态,CPU 占用情况,以及整个系统中的线程状况。从 ThreadMXBean 可以得到某一个线程的 ThreadInfo 对象。这个对象中则包含了这个线程的所有信息。

java.lang.management 和虚拟机的关系

我 们知道,management 和底层虚拟机的关系是非常紧密的。其实,有一些的是直接依靠虚拟机提供的公开 API 实现的,比如 JVMTI;而另外一些则不然,很大一块都是由虚拟机底层提供某些不公开的 API / Native Code 提供的。这样的设计方式,保证了 management 包可以提供足够的信息,并且使这些信息的提供又有足够的效率;也使 management 包和底层的联系非常紧密。

代码示例:

  1. import java.lang.management.MemoryUsage;  
  2. import java.util.Date;  
  3. import java.util.List;  
  4. import java.util.Map;  
  5.   
  6. import org.apache.commons.lang.builder.ToStringBuilder;  
  7.   
  8. /** 
  9.  * @author lisen 
  10.  * @date 2013-11-22 上午09:23:30 
  11.  */  
  12. public class SystemInfoBean {  
  13.     // 加载类的数量  
  14.     private int loadClazzCount;  
  15.     // 已经加载类的数量  
  16.     private long hasloadClazzCount;  
  17.     // 尚未加载类的数量  
  18.     private long hasUnloadClazzCount;  
  19.     // 堆内存信息  
  20.     private MemoryUsage heapMemoryUsage;  
  21.     // 非堆内存信息  
  22.     private MemoryUsage nonHeapMemoryUsage;  
  23.     // 操作系统的名称  
  24.     private String operateName;  
  25.     // 操作系统的进程数  
  26.     private int processListCount;  
  27.     // 操作系统的架构  
  28.     private String archName;  
  29.     // 操作系统的版本号码  
  30.     private String versionName;  
  31.     // 虚拟机的名称  
  32.     private String vmName;  
  33.     // 虚拟机的版本  
  34.     private String vmVersion;  
  35.     // 系统的供应商的名称  
  36.     private String vmVendor;  
  37.     // JVM启动时间  
  38.     private Date startTime;  
  39.     // 输入参数  
  40.     private List<String> arguments;  
  41.     // 系统参数  
  42.     private Map<String, String> systemProperties;  
  43.       
  44.     //setter and getter...  

  1. import java.lang.management.ClassLoadingMXBean;  
  2. import java.lang.management.ManagementFactory;  
  3. import java.lang.management.MemoryMXBean;  
  4. import java.lang.management.OperatingSystemMXBean;  
  5. import java.lang.management.RuntimeMXBean;  
  6. import java.util.Date;  
  7.   
  8. /** 
  9.  * @author lisen 
  10.  * @date 2013-11-22 上午09:27:03 
  11.  */  
  12. public class SystemInfoUtils {  
  13.   
  14.     private SystemInfoBean infoBean = null;  
  15.   
  16.     private static class SingletonClassInstance {  
  17.         private static final SystemInfoUtils instance = new SystemInfoUtils();  
  18.     }  
  19.   
  20.     public static SystemInfoUtils getInstance() {  
  21.         return SingletonClassInstance.instance;  
  22.     }  
  23.   
  24.     private SystemInfoUtils() {  
  25.         infoBean = new SystemInfoBean();  
  26.   
  27.         // 操作系统信息  
  28.         OperatingSystemMXBean operateSystemMBean = ManagementFactory  
  29.                 .getOperatingSystemMXBean();  
  30.         String operateName = operateSystemMBean.getName();  
  31.         infoBean.setOperateName(operateName);  
  32.         int processListCount = operateSystemMBean.getAvailableProcessors();  
  33.         infoBean.setProcessListCount(processListCount);  
  34.         String archName = operateSystemMBean.getArch();// System.getProperty("os.arch");  
  35.         infoBean.setArchName(archName);  
  36.         String versionName = operateSystemMBean.getVersion();// System.getProperty("os.version");  
  37.         infoBean.setVersionName(versionName);  
  38.   
  39.         // 运行时信息  
  40.         RuntimeMXBean runtimeMXBean = ManagementFactory.getRuntimeMXBean();  
  41.         String vmName = runtimeMXBean.getVmName();  
  42.         infoBean.setVmName(vmName);  
  43.         String vmVersion = runtimeMXBean.getVmVersion();  
  44.         // infoBean.setVmVersion(vmVersion);  
  45.         infoBean.setVmVersion(System.getProperty("java.version") + " ("  
  46.                 + vmVersion + ")");  
  47.         String vmVendor = runtimeMXBean.getVmVendor();  
  48.         infoBean.setVmVendor(vmVendor);  
  49.         long startTime = runtimeMXBean.getStartTime();  
  50.         infoBean.setStartTime(new Date(startTime));  
  51.   
  52.         infoBean.setArguments(runtimeMXBean.getInputArguments());  
  53.         infoBean.setSystemProperties(runtimeMXBean.getSystemProperties());  
  54.     }  
  55.   
  56.     public SystemInfoBean getSystemInfo() {  
  57.         // 类信息  
  58.         ClassLoadingMXBean classLoadMXBean = ManagementFactory  
  59.                 .getClassLoadingMXBean();  
  60.         int loadClazzCount = classLoadMXBean.getLoadedClassCount();  
  61.         infoBean.setLoadClazzCount(loadClazzCount);  
  62.         long hasloadClazzCount = classLoadMXBean.getTotalLoadedClassCount();  
  63.         infoBean.setHasloadClazzCount(hasloadClazzCount);  
  64.         long hasUnloadClazzCount = classLoadMXBean.getUnloadedClassCount();  
  65.         infoBean.setHasUnloadClazzCount(hasUnloadClazzCount);  
  66.   
  67.         // 内存  
  68.         MemoryMXBean memoryUsage = ManagementFactory.getMemoryMXBean();  
  69.         infoBean.setHeapMemoryUsage(memoryUsage.getHeapMemoryUsage());  
  70.         infoBean.setNonHeapMemoryUsage(memoryUsage.getNonHeapMemoryUsage());  
  71.         return infoBean;  
  72.     }  

猜你喜欢

转载自ximeng1234.iteye.com/blog/2288779
JMX