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部分的截图):
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 GarbageCollectorMXBean
extends java.lang.management.GarbageCollectorMXBean
{
GcInfo getLastGcInfo();
}
我们可以通过下面的截图了解GcInfo包含的主要信息
其中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我们可以通过下图来了解其提供的主要信息
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 OperatingSystemMXBean
extends 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<String> 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");
//Detach
virtualmachine.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实现自动的性能监控
分享到:
相关推荐
7. **性能监控**:SAP JVM提供了丰富的JMX(Java Management Extensions)和JFR(Java Flight Recorder)功能,帮助管理员监控和分析JVM的性能,如内存使用、线程状态、GC(垃圾收集)行为等。 总之,SAP JVM 8.1 ...
要使用JVM TI,开发者通常需要编写一个本地代理(Agent)程序,这个程序作为Java虚拟机的插件,通过JVM TI API与JVM进行通信。代理程序可以是动态链接库(在Windows上是.DLL,在Linux上是.SO文件),在JVM启动时通过...
JVM 内部组件包括类装载器(ClassLoader)、内存管理(Memory Management)、诊断接口(Diagnostics Interface)和类解释器(Interpreter)。平台相关接口主要用于跨操作系统平台重用 JVM 代码。 内存管理 内存...
要启用JMX,需在JVM启动时添加特定的系统属性,如`-Dcom.sun.management.jmxremote`。 2. **安全配置**: 为了防止未经授权的访问,需要配置JMX安全策略,包括设置访问控制和认证。 3. **端口设置**: JMX默认使用...
- **-Dcom.ibm.tools.attach.enable**: 允许应用程序使用Attach API连接到正在运行的JVM实例。 - **-Dcom.ibm.UseCLDR16**: 控制是否使用最新的CLDR(Common Locale Data Repository)版本16。 - **-Dcom.ibm.xtq...
JMX(Java Management Extensions)是Java平台的一部分,用于管理和监控应用程序,包括JVM自身。在这个主题中,我们将深入探讨JVM与JMX在Java环境中的交互以及它们如何增强Java应用的管理和维护能力。 **JVM详解** ...
- JMX(Java Management Extensions):用于监控和管理Java应用的工具和API。 - JConsole和VisualVM:两款常用的JVM性能分析工具,可以查看内存、线程、类加载等信息。 - 参数调整:学习如何通过JVM参数设置内存...
javax.management.remote.rmi RMI 连接器是供 JMX Remote API 使用的一种连接器,后者使用 RMI 将客户端请求传输到远程 MBean 服务器。 javax.management.timer 提供对 Timer MBean(计时器 MBean)的定义。 javax...
使用JMX(Java Management Extensions)可以远程监控JVM。通过持续监控并分析性能数据,我们可以发现潜在的性能瓶颈,进而进行针对性优化。 七、线程与并发 在多线程环境中,JVM需要管理线程的创建、同步和销毁。...
- **JMX(Java Management Extensions)**:提供标准API来管理资源。 #### 8. jvm堆分析 堆分析是诊断内存泄漏的关键手段之一。常用的堆分析工具包括: - **MAT(Memory Analyzer Tool)**:强大的内存分析工具。 -...
### JMX API for Monitoring and Management #### 引言:JMX API概述 Java Management Extensions (JMX) 是一种用于管理应用程序、开发工具和运行时环境的框架。它为监控和管理Java应用程序提供了一套标准的方法。...
- **JVM API**:用于与JVM交互的API集合。 - **Diagnostics Component**:提供故障排查功能的组件。 - **Memory Management**:内存管理机制,包括垃圾回收和其他内存管理策略。 - **Class Loader**:加载类和...
它定义了一种模型来表示管理系统资源(如JVM、网络连接等),并提供了API来访问和操作这些资源。"HelloAgent.java"可能是实现了一个JMX代理,它注册了MBean(Managed Bean),MBean是JMX中的核心概念,代表可管理的...
"doc"文件夹可能包含JVM的官方文档、API参考、开发者指南等,帮助开发者学习JVM的工作原理、配置选项和最佳实践。 9. **JVM与多线程**: JVM支持多线程,每个线程有自己的程序计数器、虚拟机栈和本地方法栈,共享...
10. **Java虚拟机(JVM)工具**:`java.lang.management`包提供了管理JVM和其他操作系统资源的接口,如内存管理、线程监控。 `1+1.txt`文件名可能是一个简单的示例或测试文件,通常用于教学目的,展示基本的文本...
javax.management.remote.rmi RMI 连接器是供 JMX Remote API 使用的一种连接器,后者使用 RMI 将客户端请求传输到远程 MBean 服务器。 javax.management.timer 提供对 Timer MBean(计时器 MBean)的定义。 javax....
Java 1.7 API作为Java SE 7的核心组成部分,不仅在API层面引入了许多重要的改进,还在JVM层面进行了多方面的优化,以提高程序的性能和稳定性。对于开发者而言,了解这些新特性不仅可以提高开发效率,还能帮助构建更...
8. **JMX(Java Management Extensions)增强**:提供更方便的管理和监控Java应用程序的能力,通过MBeans进行系统资源的监控和管理。 9. **国际化和本地化改进**:增加了对更多语言和地区的支持,包括日期、时间、...
javax.management.remote.rmi RMI 连接器是供 JMX Remote API 使用的一种连接器,后者使用 RMI 将客户端请求传输到远程 MBean 服务器。 javax.management.timer 提供对 Timer MBean(计时器 MBean)的定义。 javax....
- 引入JMX(Java Management Extensions)的概念及其应用。 - 如何使用JDK自带的jmap、jhat、jstack等命令行工具进行问题诊断。 7. **编译与执行** - JIT(Just-In-Time)编译器的作用,如何提高代码运行速度。 ...