JVM mangement API

摘要:JVM本身提供了一组管理的API,通过该API,我们可以获取得到JVM内部主要运行信息,包括内存各代的数据、JVM当前所有线程及其栈相关信息等等。各种JDK自带的剖析工具,包括jps、jstack、jinfo、jstat、jmap、jconsole等,都是基于此API开发的。本篇对这部分内容进行一个详细的说明。参考:http://java.sun.com/javase/6/docs/api/java/lang/management/package-summary.html一、
JVM本身提供了一组管理的API,通过该API,我们可以获取得到JVM内部主要运行信息,包括内存各代的数据、JVM当前所有线程及其栈相关信息等等。各种JDK自带的剖析工具,包括jps、jstack、jinfo、jstat、jmap、jconsole等,都是基于此API开发的。本篇对这部分内容进行一个详细的说明。

参考:http://java.sun.com/javase/6/docs/api/java/lang/management/package-summary.html
一、Management API
我们先看一下从Sun JVM我们可以获取到哪些信息,如下图(来自于JConsole的MBean部分的截图):

JVM Management API_Java

1.HotSpotDiagnostic:非标准的监控JMX,这块是Sun JVM自带的,主要提供了两个功能

修改JVM的启动参数(譬如在不需要重启的情况下设置-XX:+HeapDumpOnOutOfMemoryError参数使得JVM内存不足的时候自动dump出堆空间到文件提供后续分析) Dump堆信息到文件,可以猜测jmap工具是基于此功能来完成的
我们通过com.sun.management.HotSpotDiagnosticMXBean定义了解其主要功能

public interface HotSpotDiagnosticMXBean{void dumpHeap(String s, boolean flag) throws IOException;List getDiagnosticOptions();VMOption getVMOption(String s);void setVMOption(String s, String s1);}
2.ClassLoading:加载的类的总体信息,我们可以通过此MBean获取到JVM加载的类定义的总体信息,可以猜测JConsole的类功能就是通过此MBean来提供的。我们可以通过java.lang.management.ClassLoadingMXBean定义了解其提供的主要功能

public interface ClassLoadingMXBean {public long getTotalLoadedClassCount();public int getLoadedClassCount();public long getUnloadedClassCount();public boolean isVerbose();public void setVerbose(boolean value);}
3.Compilation:提供JVM的JIT(Just In Time)编译器(将bytecode编译成native code)的信息,我们可以通过java.lang.management.CompilationMXBean定义了解其提供的主要功能

public interface CompilationMXBean {public java.lang.String getName();public boolean isCompilationTimeMonitoringSupported();public long getTotalCompilationTime();}
4.GarbageCollector:垃圾回收器信息,譬如在如上图中,我们启动的JVM会包含一个Copy垃圾回收器(用于Young Gen垃圾回收)和一个MarkAndSweep垃圾回收器(用于Tenured Gen垃圾回收)。我们可以通过java.lang.management.GarbageCollectorMXBean定义了解其提供的主要功能

public interface GarbageCollectorMXBean extends MemoryManagerMXBean {public long getCollectionCount();public long getCollectionTime();}
java.lang.management.MemoryManagerMXBean定义是

public interface MemoryManagerMXBean {public String getName();public boolean isValid();public String[] getMemoryPoolNames();}
除了如上信息,Sun JVM在实现上还提供了一个额外的信息LastGCInfo,见com.sun.management.GarbageCollectorMXBean定义

public interface GarbageCollectorMXBeanextends java.lang.management.GarbageCollectorMXBean{GcInfo getLastGcInfo();}
我们可以通过下面的截图了解GcInfo包含的主要信息

JVM Management API_Java

其中java.lang.management.MemoryUsage后续可以看说明
5.内存相关
可以猜测,JConsole的内存部分的功能都是通过此部分的相关Bean来完成的。
1)Memory/MemoryManager:内存块相关信息,通过这MBean我们可以获取到内存的总体信息,并可以通过提供的gc操作进行强制gc的功能(System.gc())。我们可以通过java.lang.management.MemoryMXBean和java.lang.management.MemoryManagerMXBean了解其主要提供的功能

public interface MemoryMXBean {public int getObjectPendingFinalizationCount();public MemoryUsage getHeapMemoryUsage();public MemoryUsage getNonHeapMemoryUsage();public boolean isVerbose();public void setVerbose(boolean value);public void gc();}
其中java.lang.management.MemoryUsage我们可以通过下图来了解其提供的主要信息

JVM Management API_Java public interface MemoryManagerMXBean {public String getName();public boolean isValid();public String[] getMemoryPoolNames();}
2)MemoryPool:通过该MBean可以了解JVM各内存块的信息,譬如对于Sun JVM,目前包括Eden Space、Suvivor Space、Tenured Gen、CodeCache、Perm Gen,可以猜测JConsole的内存监控功能就是通过此MBean来做到的。我们可以通过java.lang.management.MemoryPoolMXBean了解其主要提供的功能

public interface MemoryPoolMXBean {public String getName();public MemoryType getType();public MemoryUsage getUsage();public MemoryUsage getPeakUsage();public void resetPeakUsage();public boolean isValid();public String[] getMemoryManagerNames();public long getUsageThreshold();public void setUsageThreshold(long threshold);public boolean isUsageThresholdExceeded();public long getUsageThresholdCount();public boolean isUsageThresholdSupported();public long getCollectionUsageThreshold();public void setCollectionUsageThreshold(long threhsold);public boolean isCollectionUsageThresholdExceeded();public long getCollectionUsageThresholdCount();public MemoryUsage getCollectionUsage();public boolean isCollectionUsageThresholdSupported();}
6.系统运行信息
1)OperatingSystem:通过该MBean我们可以了解到JVM所运行在的操作系统上的一些相关信息,通过java.lang.management.OperatingSystemMXBean定义我们可以了解到其主要提供的功能

public interface OperatingSystemMXBean {public String getName();public String getArch();public String getVersion();public int getAvailableProcessors();public double getSystemLoadAverage();}
SunJVM在此基础上提供更多的一些信息,可以通过com.sun.management.OperatingSystemMXBean了解一些额外可以获取到的信息

public interface OperatingSystemMXBeanextends java.lang.management.OperatingSystemMXBean{long getCommittedVirtualMemorySize();long getTotalSwapSpaceSize();long getFreeSwapSpaceSize();long getProcessCpuTime();long getFreePhysicalMemorySize();long getTotalPhysicalMemorySize();}
2)Runtime:通过该MBean获取获取到JVM一些相关的信息,通过java.lang.management.RuntimeMXBean可以了解其主要提供的功能

public interface RuntimeMXBean {public String getName();public String getVmName();public String getVmVendor();public String getVmVersion();public String getSpecName();public String getSpecVendor();public String getSpecVersion();public String getManagementSpecVersion();public String getClassPath();public String getLibraryPath();public boolean isBootClassPathSupported();public String getBootClassPath();public java.util.List getInputArguments();public long getUptime();public long getStartTime();public java.util.Map<String, String> getSystemProperties();}
可以通过RuntimeMXBean.getUptime()和OperatingSystemMXBean. getProcessCpuTime()来计算JVM占用的系统CPU比例的情况,JConsole的CPU视图就是通过这种方式计算的。
7.Threading:可以通过该MBean获取线程信息,包括线程状态、执行栈等。可以通过java.lang.management.ThreadMXBean了解其提供的主要功能

public interface ThreadMXBean { public int getThreadCount();public int getPeakThreadCount();public long getTotalStartedThreadCount(); public int getDaemonThreadCount();public long[] getAllThreadIds();public ThreadInfo getThreadInfo(long id);public ThreadInfo[] getThreadInfo(long[] ids);public ThreadInfo getThreadInfo(long id, int maxDepth);public ThreadInfo[] getThreadInfo(long[] ids, int maxDepth);public boolean isThreadContentionMonitoringSupported();public boolean isThreadContentionMonitoringEnabled();public void setThreadContentionMonitoringEnabled(boolean enable);public long getCurrentThreadCpuTime();public long getCurrentThreadUserTime();public long getThreadCpuTime(long id);public long getThreadUserTime(long id);public boolean isThreadCpuTimeSupported();public boolean isCurrentThreadCpuTimeSupported();public boolean isThreadCpuTimeEnabled();public void setThreadCpuTimeEnabled(boolean enable);public long[] findMonitorDeadlockedThreads();public void resetPeakThreadCount();public long[] findDeadlockedThreads();public boolean isObjectMonitorUsageSupported();public boolean isSynchronizerUsageSupported();public ThreadInfo[] getThreadInfo(long[] ids, boolean lockedMonitors, boolean lockedSynchronizers);public ThreadInfo[] dumpAllThreads(boolean lockedMonitors, boolean lockedSynchronizers);}
二、编程获取到JVM Manage信息
我们可以通过JMX的方式读取到JVM Manage定义的MBean,如下是3种获取方法
1.监控应用与被监控应用位于同一JVM

MBeanServer server = ManagementFactory.getPlatformMBeanServer();RuntimeMXBean rmxb = ManagementFactory.newPlatformMXBeanProxy(server,“java.lang:type=Runtime”, RuntimeMXBean.class);
2.监控应用与被监控应用不位于同一JVM
1)首先在被监控的JVM的启动参数中加入如下的启动参数以启JVM代理

-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=127.0.0.1:8000 -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

2)连接到代理上

JMXServiceURL url = new JMXServiceURL(“service:jmx:rmi:///jndi/rmi://127.0.0.1:8000/jmxrmi”);JMXConnector connector = JMXConnectorFactory.connect(url);RuntimeMXBean rmxb = ManagementFactory.newPlatformMXBeanProxy(connector.getMBeanServerConnection(),“java.lang:type=Runtime”,RuntimeMXBean.class);
3.监控应用与被监控应用不位于同一JVM但在同一物理主机上(2的特化情况,通过进程Attach)
我们使用JDK工具,如jmap、jstack等的时候,工具所在的JVM当然与被监控的JVM不是同一个,所以不能使用方式1,被监控的JVM一般也不会在启动参数中增加JMX的支持,所以方式2也没有办法。还好Sun JVM给我们提供了第3种非标准的方式,就是通过Attach到被监控的JVM进程,并在被监控的JVM中启动一个JMX代理,然后使用该代理通过2的方式连接到被监控的JVM的JMX上。下面是一个使用范例,由于里面使用到的知识涉及到Java Instrutment(JVMTI的一个技术的Java实现)和Attach API,因此此处不做详细解析,在后续看完Java Instrutment和Attach API自然就会明白。(注意,仅在JDK6+中支持,另外,运行需要jdk的tools.jar包)

//Attach 到5656的JVM进程上,后续Attach API再讲解VirtualMachine virtualmachine = VirtualMachine.attach(“5656”);//让JVM加载jmx Agent,后续讲到Java Instrutment再讲解String javaHome = virtualmachine.getSystemProperties().getProperty(“java.home”);String jmxAgent = javaHome + File.separator + “lib” + File.separator + “management-agent.jar”;virtualmachine.loadAgent(jmxAgent, “com.sun.management.jmxremote”);//获得连接地址Properties properties = virtualmachine.getAgentProperties();String address = (String)properties.get(“com.sun.management.jmxremote.localConnectorAddress”);//Detachvirtualmachine.detach();JMXServiceURL url = new JMXServiceURL(address);JMXConnector connector = JMXConnectorFactory.connect(url);RuntimeMXBean rmxb = ManagementFactory.newPlatformMXBeanProxy(connector.getMBeanServerConnection(), “java.lang:type=Runtime”,RuntimeMXBean.class);
三、结束语
可以看到,通过标准的接口,我们已经可以获得运行的JVM很详细的信息,从运行JVM、操作系统,到内存、GC和线程,通过这些标准的接口我们已经可以对JVM进行功能完善的监控。但是仅此是不够的,这部分接口描述的主要是JVM的总体性的信息,而无法提供更多的细节。在下一部分,我们将使用JPDA来更深入地了解JVM内部信息更细节的信息,并了解我们如何通过JVM TI实现自动的性能监控

以上是JVM Management API的内容,更多 的内容,请您使用右上方搜索功能获取相关信息。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值