JVM平台提供Mbeans说明
在 Java2 平台5.0以上版本,有一组API可以让Java应用程序和允许的工具监视和管理Java虚拟机(JVM)和虚拟机所在的本机操作系统。该组API在java.lang.management。可以通过这些API可以监控local端JVM,同时也可以监控远端JVM
Java平台提供了如下一些接口用于管理JVM平台
ClassLoadingMXBeanJava 虚拟机的类加载系统。
CompilationMXBeanJava 虚拟机的编译系统。
MemoryMXBeanJava 虚拟机的内存系统。
ThreadMXBeanJava 虚拟机的线程系统。
RuntimeMXBeanJava 虚拟机的运行时系统。
OperatingSystemMXBeanJava 虚拟机在其上运行的操作系统。
GarbageCollectorMXBeanJava 虚拟机中的垃圾回收器。
MemoryManagerMXBeanJava 虚拟机中的内存管理器。
MemoryPoolMXBeanJava 虚拟机中的内存池。
这些Bean我们从 ManagementFactory类中定义。
访问Mean的方式有两种
-
直接访问 MXBean接口
-
通过静态工厂方法获取MXBean实例,从本地访问正在运行的虚拟机的MXBean接口。
-
构造MXBean代理实例,通过调用ManagementFactory.newPlatformMXBeanProxy将方法调用转发到给定的MBeanServer。代理通常构造为远程访问另一个正在运行的虚拟机的MXBean。
-
通过 MBeanServer接口间接访问(暂时还没来的及研究)
例:
直接调用同一Java虚拟机内的MXBean中的方法。
- import java.lang.management.ManagementFactory;
- import java.lang.management.OperatingSystemMXBean;
- import java.lang.management.ThreadMXBean;
- public class JmxLocal {
- public static void main(String[] args) {
- OperatingSystemMXBean osbean = ManagementFactory
- .getOperatingSystemMXBean();
- System.out.println(osbean.getArch());//操作系统体系结构
- System.out.println(osbean.getName());//操作系统名字
- System.out.println(osbean.getAvailableProcessors());//处理器数目
- System.out.println(osbean.getVersion());//操作系统版本
- ThreadMXBean threadBean=ManagementFactory.getThreadMXBean();
- System.out.println(threadBean.getThreadCount());//总线程数
- }
- }
使用 MXBean代理。访问远程Mbean
- import java.lang.management.ManagementFactory;
- import java.lang.management.ThreadMXBean;
- import javax.management.MBeanServerConnection;
- import javax.management.remote.JMXConnector;
- import javax.management.remote.JMXConnectorFactory;
- import javax.management.remote.JMXServiceURL;
- public class JmxRemote {
- public static void main(String[] args) {
- try {
- // connect to a separate VM's MBeanServer, using the JMX RMI functionality
- JMXServiceURL address = new JMXServiceURL( "service:jmx:rmi:///jndi/rmi://localhost:9999/jmxrmi");
- JMXConnector connector = JMXConnectorFactory.connect(address);
- MBeanServerConnection mbs = connector.getMBeanServerConnection();
- ThreadMXBean threadBean = ManagementFactory.newPlatformMXBeanProxy
- (mbs, ManagementFactory.THREAD_MXBEAN_NAME, ThreadMXBean.class);
- System.out.println(threadBean.getThreadCount());//线程数量
- } catch(Exception e){
- e.printStackTrace();
- }
- }
- }
如果要远程访问,被访问Mbean服务器首选需要命令行选项启动远程虚拟机,这些选项设置虚拟机的相关JMX代理侦听请求的端口,以及起作用的安全级别
如下:
-Dcom.sun.management.jmxremote.port=9999 --指定端口
-Dcom.sun.management.jmxremote.authenticate=false–指定是否需要密码验证
-Dcom.sun.management.jmxremote.ssl=false–指定是否使用SSL通讯
例:我要测试下面运用程序
- public class Test {
- public static void main(String[] args) {
- Thread thread=new Thread();
- thread.run();
- try {
- thread.sleep(100000);
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- System.out.println("Success");
- }
- }
启动上面运用程序时在VMarguments加上如上配置
远程监控Jboss或者weblogic需要配置如下:
Jboss设置:
-
找到run.bat文件(linux环境下是run.sh)文件,有一行
setJAVA_OPTS=%JAVA_OPTS% -Dprogram.name=%PROGNAME%
改成
setJAVA_OPTS=%JAVA_OPTS% -Dprogram.name=%PROGNAME%
-Dcom.sun.management.jmxremote.port=9999-Dcom.sun.management.jmxremote.authenticate=false-Dcom.sun.management.jmxremote.ssl=false
Weblogic设置:
-
找到你要监控domain下的startWebLogic.cmd文件(linux环境下是startWebLogic.sh)文件、将文件中
setJAVA_OPTIONS=%SAVE_JAVA_OPTIONS%
改成
set JAVA_OPTIONS=%SAVE_JAVA_OPTIONS%
-Dcom.sun.management.jmxremote.port=9998-Dcom.sun.management.jmxremote.authenticate=false-Dcom.sun.management.jmxremote.ssl=false
Jconsole使用说明:
启动jconsole
jconsole是JVM自带管理Mbean的图形化界面
环境变量中path中加上
C:\ProgramFiles\Java\jdk1.6.0_01\bin
在控制台中敲jconsole
一个用于连接的对话框将会打开。对话框的本地进程列出本地JVM,中进程的ID
你会看到两种方式,一种是本地进程,另外一种连接方式远程进程
当JConsole成功建立连接,它从连接上的JMX代理处获取信息,并且以下面几个标签页呈现信息。
概述tab. 监控JVM主要图形
内存tab. 内存使用信息
线程tab. 线程使用信息
类 tab. 类调用信息
VM摘要 tab.JVM的信息
MBeanstab. 所有MBeans的信息
如下图:
MBeanstab展示了所有以一般形式注册到JVM上的MBeans。MBeanstab允许你获取所有的平台信息,包括那些不能从其他标签页获取到的信息。注意,其他标签页上的一些信息也在MBeans这里显示。另外,你可以使用MBeans标签管理你自己的应用的MBeans。当然你也可以添加其它工具提供的MBeans例如Jboss,weblogic连接池信息
内存管理:
管理内存有如下几个Mbeans:
MemoryMXBean Java 虚拟机内存系统
MemoryManagerMXBeanJava 虚拟机中的内存管理器。
MemoryPoolMXBeanJava 虚拟机中的内存池。
MemoryPoolMXBean说明:
注册到JMX代理的平台或者应用的MBeans,可以通过MBeans标签获取。例如,MemoryMXBean如下面定义
- public interface MemoryMXBean {
- public MemoryUsage getHeapMemoryUsage();
- public MemoryUsage getNonHeapMemoryUsage();
- public int getObjectPendingFinalizationCount();
- public boolean isVerbose();
- public void setVerbose(boolean value);
- public void gc();
- }
MemoryMXBean包括四个属性:
-
HeapMemoryUsage.用于描述当前堆内存使用情况的只读属性
-
NonHeapMemoryUsage.用于描述当前的非堆内存的使用情况的只读属性
-
ObjectPendingFinalizationCount.用于描述有多少对象被挂起以便回收。
-
Verbose.用于动态设置GC是否跟着详细的堆栈信息,为一个布尔变量
内存的MBean支持一个操作——GC,此操作可以发送进行实时的垃圾回收请求。
(
Heap—NonHeap内存说明:
程序运行时存储数据主要有:寄存器,堆栈,堆,常量存储,非RAM存储
速度由高到低。
-
堆内存类型(Heap):Java虚拟机具有一个堆,堆是运行时数据区域,所有类实例和数组的内存均从此处分配。
-
非堆内存类型(Non-Heap):Java虚拟机管理堆之外的内存(称为非堆内存)。非堆内存包括方法区和 Java虚拟机的内部处理或优化所需的内存。它存储每个类结构,如运行时常数池、字段和方法数据,以及方法和构造方法的代码。
)
监控内存(MemoryPoolMXBean)
内存标签页通过读取内存系统、内存池、垃圾回收的MBean来获取对内存消耗、内存池、垃圾回收的情况的统计。
主要统计随时间变化,对堆的、非堆的以及特殊内存池的统计如下图
右下角分别绿色竖条分别表示如下(前面三项堆内内存,后面三项非堆内内存)
EdenSpace (heap):内存最初从这个线程池分配给大部分对象。
SurvivorSpace (heap):用于保存在edenspace内存池中经过垃圾回收后没有被回收的对象。
TenuredGeneration (heap):用于保持已经在survivorspace内存池中存在了一段时间的对象。
PermanentGeneration (non-heap):保存虚拟机自己的静态(refective)数据,例如类(class)和方法(method)对象。Java虚拟机共享这些类数据。这个区域被分割为只读的和只写的,
CodeCache (non-heap):HotSpotJava虚拟机包括一个用于编译和保存本地代码(nativecode)的内存,叫做“代码缓存区”(codecache)
详细信息区域
已经使用:已使用:当前的内存使用量。使用的内存包括所有对象占用内存
分配: Java虚拟机保证能够获取到的内存量。分配内存的量可能随时间改变。Java虚拟机可能释放部分这里的内存给系统,相应的分配的内存这时可能少于初始化时分配的给它的量。分配量总数大于或等于已使用的内存量。
最大值:内存管理系统可以使用的最大内存量。这个值可以被改变或者不做设定。如果JVM试图增加使用的内存到大于分配量,内存分配可能失败这就是我们在起web服务时常出现内存不够状况
分配和最大值我们都可以在运用服务启动时指定
例如:启动时设定:
-Xms512m -Xmx1024m
-Xms512m为分配量,1024m为最大分配量
垃圾回收(GarbageCollectorMXBean)
提供两个接口
longgetCollectionCount()
longgetCollectionTime()
GC时间:垃圾回收使用的总时间和调用垃圾回收的次数。通过
getCollectionTime()/getCollectionCount()
内存池( MemoryPoolMXBean)
提供内存管理接口,API详细介绍请看http://gceclub.sun.com.cn/Java_Docs/jdk6/html/zh_CN/api/java/lang/management/MemoryPoolMXBean.html#setCollectionUsageThreshold%28long%29
UsageThreshold(使用量阈值)
usagethreshold是内存池中一个可管理的属性。默认值由JVM设置。可以通过setUsageThreshold方法设置使用量阈值。如果阈值设置为正数,将启用此内存池中的使用量阈值超过检查。如果使用率阈值设置为零,将禁用此内存池的使用量阈值超过检查。isUsageThresholdSupported()方法可用于确定是否支持此功能。
Java虚拟机在其最恰当的时候(通常在垃圾回收时)会对内存池逐个进行使用量阈值超过检查。每个内存池均维护一个使用量阈值计数,每次Java虚拟机检测到内存池使用量超过阈值,此值都会加1。getUsageThresholdCount()可以取得超过使用量阈值的次数
CollectionUsage Threshold(回收使用量阈值)
<!--@page { margin: 2cm }P { margin-bottom: 0.21cm }-->
Collectionusage threshold是可进行垃圾回收的内存池的一个可配置属性。JVM堆一个内存池进行垃圾回收以后,此内存池中的一些内存仍然被那些没有被回收的对象占用。collectionusage threshold仅允许你在垃圾回收后对内存进行检查。如果JVM发现可用内存超出collectionusagethreshold,它将会设置CollectionUsageThresholdExceeded属性为true。你可以使用CollectionUsageThresholdSupported属性来控制内存池释放支持collectionusage threshold.
<!--@page { margin: 2cm }P { margin-bottom: 0.21cm }-->
usagethreshold 和collectionusage threshold在Jconsole中MBean设置
如果超过设定值,内存Tab会出现如下: