Jconsole与Jmx 分析JVM状况(上)

来源:转载

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 functionalityJMXServiceURL 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(回收使用量阈值)

<[email protected] { margin: 2cm }P { margin-bottom: 0.21cm }-->

Collectionusage threshold是可进行垃圾回收的内存池的一个可配置属性。JVM堆一个内存池进行垃圾回收以后,此内存池中的一些内存仍然被那些没有被回收的对象占用。collectionusage threshold仅允许你在垃圾回收后对内存进行检查。如果JVM发现可用内存超出collectionusagethreshold,它将会设置CollectionUsageThresholdExceeded属性为true。你可以使用CollectionUsageThresholdSupported属性来控制内存池释放支持collectionusage threshold.

<[email protected] { margin: 2cm }P { margin-bottom: 0.21cm }-->

usagethreshold 和collectionusage threshold在Jconsole中MBean设置

如果超过设定值,内存Tab会出现如下:

大小: 50.2 KB 大小: 30.1 KB 大小: 50.7 KB 大小: 43.9 KB 大小: 85.6 KB 大小: 11.7 KB 大小: 42.9 KB 大小: 10.9 KB 大小: 67 KB 大小: 94 KB 大小: 2.4 KB 大小: 18.2 KB 大小: 17.7 KB 大小: 24.7 KB

分享给朋友:
您可能感兴趣的文章:
随机阅读: