使用JCONSOLE远程监控JVM

启动JMS服务

JConsole是从Java 5中开始引入的一个用于对JVM性能和资源消耗进行监控的图形化工具。
JConsole可以连接本地的Java程序,也可以连接远程的Java程序。由于是GUI的方式使用,所以就不细说那些基本的使用方法了,这里只是记录一下试用过程中遇到的几个小问题及其解决方案。

1. 要实现让JConsole可以远程连接到某个Java程序,则需要在Java程序启动的JAVA_OPTION中添加选项“com.sun.management.jmxremote.port=8888”来指定远程管理的端口。

2. 启动Java程序时,遇到如下报错:

Thu Jul  :: CST 

./jbb.jar:./check.jar:
java full version "1.6.0_24-b24"
Error: Password file not found: /usr/lib/jvm/java-1.6.-openjdk-1.6.0.0.x86_64/jre/lib/management/jmxremote.password
Thu Jul :: CST

这是由于开启Java JMX 远程管理时,默认会有用户名密码的验证,所以需要相应的密码文件。

[root@localhost SPECjbb2005]# ls /usr/lib/jvm/java-1.6.-openjdk-1.6.0.0.x86_64/jre/lib/management/
jmxremote.access jmxremote.password.template management.properties snmp.acl.template

需要先在jmxremote.access中定义用户权限,然后在jmxremote.password文件中定义用户名和对应的密码,jmxremote.password文件可以复制jmxremote.password.template模板文件来进行修改。
当然,在内网中仅仅用于调试,我们一般可以不设置密码验证和SSL连接方式,Java选项如下:
-Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false

报错:

Error: Password file read access must be restricted: /usr/java/jdk1..0_60/jre/lib/management/jmxremote.password

在配置JMX远程访问的时候,设置jmxremote.password文件权限,修改该文件时添加写权限,chmod +w jmxremote.password ,放开角色信息那俩行的注释,保存,再使用chmod 0400 jmxremote.password

这样就是它正确的权限设置

jmxremote.password 在jdk/jre/lib/management/下,jmxremote.password.template复制,去掉.template后缀

3. 在进行了端口和认证信息的配置后,发现在JConsole中通过IP远程连接JVM依然不成功。
错误信息为:Connection Failed: Retry? The connection to 192.168.52.11:8888 did not succeed. Would you like to try again?
在启动Java时,需要设置RMI远程调用的主机名,一般设置为主机的IP地址即可,如下:
-Djava.rmi.server.hostname=192.168.52.11
(当然,也有可能是由于前面第2点中提到的SSL的设置问题,依然需要检查一下)

关于JConsole,还是得执行看看Oracle的这篇Java SE 6 中的JConsole的描述:
http://docs.oracle.com/javase/6/docs/technotes/guides/management/jconsole.html
(特别是上面文档中对监控数据、图形代表的意义是需要认真理解的)

Using JConsole

JConsole图形用户界面是符合Java Management Extensions(JMX)规范的监视工具。JConsole使用Java虚拟机(Java VM)的大量工具来提供有关在Java平台上运行的应用程序的性能和资源消耗的信息。

在Java平台标准版(Java SE平台)6中,JConsole已更新,以呈现Windows和GNOME桌面的外观(其他平台将呈现标准的Java图形外观)。本文档中提供的屏幕截图取自在Windows XP上运行的界面实例。

Starting JConsole

jconsole可执行文件可以在JDK_HOME / bin中找到,其中JDK_HOME是Java开发工具包(JDK)的安装目录。如果此目录位于系统路径中,则只需在命令(shell)提示符下键入jconsole即可启动JConsole。否则,您必须输入可执行文件的完整路径。

Command Syntax

您可以使用JConsole监视本地应用程序,即与JConsole在同一系统上运行的应用程序,以及远程应用程序,即在其他系统上运行的应用程序。

注 - 使用JConsole监视本地应用程序对于开发和创建原型非常有用,但不建议在生产环境中使用,因为JConsole本身会消耗大量的系统资源。建议使用远程监控将JConsole应用程序与正在监控的平台隔离。

有关jconsole命令的语法的完整参考,请参阅jconsole命令的手册页:Java监视和管理控制台。 Java Monitoring and Management Console.

Setting up Local Monitoring
Setting up Remote Monitoring

要启动JConsole进行远程监视,请使用以下命令语法:

% jconsole hostName:portNum

在上面的命令中,hostName是运行应用程序的系统的名称,portNum是您在启动Java VM时启用JMX代理时指定的端口号。有关更多信息,请参阅远程监视和管理。

如果您未指定主机名/端口号组合,则JConsole将显示连接对话框(连接到JMX代理),以便您输入主机名和端口号。

Viewing Overview Information

“Overview”(概览)选项卡显示关于CPU使用情况,内存使用情况,线程数量以及Java VM中加载的类的图形化监视信息,所有这些都在一个屏幕中显示。

使用JCONSOLE远程监控JVM

“概览”选项卡提供了一种简单的方法,可以关联之前仅通过在多个选项卡之间切换才可用的信息。

Saving Chart Data

JConsole允许您将图表中显示的数据保存为逗号分隔值(CSV)文件。要保存图表中的数据,只需右键单击任意图表,选择保存数据为...,然后指定将保存数据的文件。您可以通过这种方式保存JConsole不同选项卡中显示的任何图表中的数据。

CSV格式通常用于电子表格应用程序之间的数据交换。CSV文件可以导入到电子表格应用程序中,并可用于在这些应用程序中创建图表。数据以两个或多个命名列显示,其中第一列代表时间戳。将文件导入电子表格应用程序后,通常需要选择第一列,并根据需要将其格式更改为“日期”或“日期/时间”。

Monitoring Memory Consumption

“内存”选项卡提供有关内存消耗和内存池的信息。

使用JCONSOLE远程监控JVM

“内存”选项卡具有“执行GC”按钮,您可以随时单击执行垃圾回收。该图表显示了随时间变化的Java VM的内存使用情况,堆内存和非堆内存以及特定内存池的使用情况。可用的内存池取决于正在使用哪个版本的Java VM。对于HotSpot Java VM,用于串行垃圾收集的内存池如下所示:

Eden Space (heap): 内存最初分配给大多数对象的池。

Survivor Space (heap): 包含在伊甸园空间的垃圾收集中存活的对象的池。

Tenured Generation(heap):包含已经存在一段时间的幸存者空间中的对象的池。

Permanent Generation (non-heap):包含虚拟机本身的所有反射数据(例如类和方法对象)的池。使用类数据共享的Java虚拟机,这一代分为只读和读写区域。

Code Cache (non-heap): HotSpot Java VM还包含代码缓存,其中包含用于编译和存储本机代码的内存。

您可以通过选择“图表”下拉菜单中的选项来显示不同的图表,以绘制这些内存池的消耗情况。此外,单击右下角的堆或非堆图条会切换显示的图表。最后,您可以通过从“时间范围”下拉菜单中的选项中进行选择来指定跟踪内存使用情况的时间范围。

有关这些内存池的更多信息,请参阅下面的垃圾收集。

“详细信息”区域显示多个当前内存指标:

Used:当前使用的内存量,包括所有对象占用的内存,可达到和不可达。

Committed:保证可供Java VM使用的内存量。提交的内存量可能随时间而改变。Java虚拟机可能会向系统释放内存,并且提交的内存量可能会少于启动时初始分配的内存量。提交的内存量总是大于或等于已用内存量。

Max:可用于内存管理的最大内存量。它的值可能会改变或者是未定义的。如果Java虚拟机尝试增加使用的内存大于提交的内存,即使使用的数量小于或等于最大值(例如,当系统虚拟内存不足时),内存分配也可能会失败。

GC time:垃圾收集的累积时间和总调用次数。它可能有多行,每行代表Java VM中使用的一个垃圾收集器算法。

右下角的条形图显示了堆和非堆内存中的内存池使用的内存。当使用的内存超过内存使用阈值时,条形会变成红色。您可以通过MemoryMXBean的属性设置内存使用率阈值。

Heap and Non-Heap Memory

Java VM管理两种内存:堆和非堆内存,这两种内存都是在Java VM启动时创建的:

  堆内存是Java VM为其分配所有类实例和数组的内存的运行时数据区域。堆可以是固定的或可变的大小。垃圾收集器是一个自动内存管理系统,为对象回收堆内存。

  非堆内存包括在Java VM的内部处理或优化所需的所有线程和内存之间共享的方法区。它存储每类结构,如运行时常量池,字段和方法数据以及方法和构造函数的代码。方法区域在逻辑上是堆的一部分,但根据实现,Java VM可能不会垃圾收集或压缩。像堆内存一样,方法区域可以是固定或可变的大小。方法区域的内存不需要是连续的。

  除了方法区域之外,Java VM可能需要内存来进行内部处理或优化,这也属于非堆内存。例如,即时(Just-In-Time,JIT)编译器需要内存来存储从Java VM代码转换来的高性能的本地机器代码。

Memory Pools and Memory Managers

内存池和内存管理器是Java VM内存系统的关键方面。

内存池表示Java VM管理的内存区域。Java虚拟机至少有一个内存池,它可能会在执行期间创建或删除内存池。内存池可以属于堆或非堆内存。

内存管理器管理一个或多个内存池。垃圾回收器是一种内存管理器,负责回收不可达对象所使用的内存。Java VM可能有一个或多个内存管理器。它可能会在执行期间添加或删除内存管理器。一个内存池可以由多个内存管理器来管理。

Garbage Collection

垃圾收集(GC)是Java VM如何释放不再被引用的对象占用的内存。通常将具有活动引用的对象视为“活着”,并且将不引用(或不可访问)的对象视为“死亡”。垃圾收集是释放死对象所使用的内存的过程。GC使用的算法和参数可能会对性能产生显着影响。

Java HotSpot VM垃圾收集器使用分代GC。世代GC利用了大多数程序符合以下概括的观察:

  他们创建了很多寿命很短的对象,例如迭代器和局部变量。

  他们创建了一些具有很长生命的对象,例如高级持久对象。

分代GC将内存分成几代,并为每个分配一个或多个内存池。当一代人使用其分配的内存时,VM会在该内存池上执行部分GC(也称为次要集合)来回收死对象所使用的内存。部分GC通常比FULL GC快得多。

Java HotSpot虚拟机定义了两代:年轻一代(有时称为“托儿所”)和老一代。年轻一代包括一个"Eden space"和两个"survivor spaces."。VM最初将所有对象分配到Eden空间,大多数对象都在那里死掉。当它执行一个次要的GC时,虚拟机将所有剩余的对象从Eden空间移动到其中一个幸存者空间。虚拟机将生存空间足够长的物体移动到老一代的“终身”空间。当终身代填满时,有一个完整的GC通常要慢得多,因为它涉及所有的活物。永久生成包含虚拟机本身的所有反射数据,例如类和方法对象。

世代的默认排列如图3-7所示:

使用JCONSOLE远程监控JVM

如果垃圾收集器已成为瓶颈,则可以通过自定义生成大小来提高性能。使用JConsole,您可以通过尝试使用垃圾收集器参数来调查性能指标的敏感性。有关更多信息,请参阅使用5.0 HotSpot VM调整垃圾回收。

Monitoring Thread Use

“线程”选项卡提供有关线程使用的信息。

使用JCONSOLE远程监控JVM

左下角的线程列表列出了所有活动的线程。如果在“过滤器”字段中输入字符串,则“线程”列表将仅显示名称中包含您输入的字符串的线程。单击“线程”列表中线程的名称可显示有关该线程的信息,包括线程名称,状态和堆栈跟踪。

该图表显示了随着时间的推移活动线程的数量。显示两行:

  红:峰值线程数  蓝色:活线程数。

线程MXBean提供了线程选项卡未涵盖的其他几个有用的操作。

findMonitorDeadlockedThreads:检测是否有任何线程在对象监视器锁上死锁。该操作返回一个死锁的线程ID数组。

getThreadInfo:返回线程信息。这包括线程当前被阻塞的名称,堆栈跟踪和监视器锁,以及哪个线程持有该锁,以及线程争用统计信息。

getThreadCpuTime:返回给定线程消耗的CPU时间

通过在MBeans树中选择Threading MXBean,可以通过MBeans选项卡访问这些附加功能。这个MXBean列出了在被监控的Java VM中访问线程信息的所有属性和操作。请参阅监视和管理MBean。

Detecting Deadlocked Threads

要检查你的应用程序是否已经遇到死锁(例如,你的应用程序似乎挂起),可以通过单击“检测死锁”按钮来检测死锁的线程。如果检测到任何死锁的线程,则会显示在“线程”选项卡旁边的新选项卡中,如图3-9所示。

使用JCONSOLE远程监控JVM

“检测死锁”按钮将检测涉及对象监视器和java.util.concurrent可拥有同步器的死锁周期(请参阅java.lang.management.LockInfo的API规范文档)。在Java SE 6中添加了对java.util.concurrent锁的监视支持。如果JConsole连接到J2SE 5.0 VM,则Detect Deadlock机制将仅查找与对象监视器相关的死锁。JConsole不会显示与可拥有的同步器相关的任何死锁。

有关线程和守护进程线程的更多信息,请参阅java.lang.Thread的API文档。

Monitoring Class Loading

类选项卡显示有关类加载的信息。

使用JCONSOLE远程监控JVM

图表绘制了随着时间的推移加载的类的数量。

红线是加载的类的总数(包括随后卸载的类)。

蓝线是当前加载的类的数量。

选项卡底部的“详细信息”部分显示自Java VM启动以来加载的类的总数,当前加载的编号和卸载的编号。您可以通过选中右上角的复选框来将类加载的跟踪设置为详细输出。

Viewing VM Information

“VM摘要”选项卡提供有关Java VM的信息。

使用JCONSOLE远程监控JVM

此选项卡中显示的信息包括以下内容。

Summary

正常运行时间:Java VM启动以来的总时间。

进程CPU时间:Java VM自启动以来消耗的CPU时间总量。

总编译时间:在JIT编译中花费的总时间。Java VM确定何时发生JIT编译。Hotspot虚拟机使用自适应编译,其中VM使用标准解释器启动应用程序,然后在运行时分析代码以检测性能瓶颈或“热点”。

Threads

活动线程:活动守护程序线程的当前数量加上非守护程序线程。

峰值:Java VM启动以来的最大活动线程数

守护线程:当前的守护线程数量。

已启动线程总数:Java VM启动后启动的线程总数,包括守护进程,非守护进程和终止线程。

Classes

当前加载的类:当前加载到内存中的类的数量。

加载的总类数:自Java VM启动以来加载到内存中的类的总数,包括随后被卸载的类。

卸载的总类数:自Java VM启动以来从内存中卸载的类的数量。

Memory

当前堆大小:堆当前占用的千字节数。

提交内存:分配给堆使用的内存总量。

最大堆大小:堆占用的最大千字节数。

终止对象:终止对象的数量。

垃圾收集器:关于垃圾收集的信息,包括垃圾收集器名称,执行的收集数量以及执行GC所花费的总时间。

Operating System

总物理内存:操作系统具有的随机存取内存(RAM)的数量。

可用物理内存:可用于操作系统的可用RAM的数量。

提交的虚拟内存:保证可用于正在运行的进程的虚拟内存量。

Other Information

VM参数:应用程序传递给Java VM的输入参数,不包括主方法的参数。

类路径:系统类加载器用于搜索类文件的类路径。

库路径:加载库时要搜索的路径列表。

引导类路径:引导类加载器使用引导类路径来搜索类文件。

Monitoring and Managing MBeans

“MBeans”选项卡以通用方式显示有关在平台MBean服务器中注册的所有MBean的信息。MBeans选项卡允许您访问整套平台MXBean工具,包括在其他选项卡中不可见的工具。另外,您可以使用MBeans选项卡监视和管理应用程序的MBean。

使用JCONSOLE远程监控JVM

左边的树显示当前正在运行的所有MBean。当您在树中选择一个MBean,它的MBeanInfo和MBean描述都显示在右侧,和任何属性,操作或通知出现在其下方的树。

所有的平台MXBeans及其各种操作和属性都可以通过JConsole的MBeans选项卡访问。

Constructing the MBean Tree

默认情况下,MBean根据其对象名称显示在树中。JConsole在将MBean添加到MBean树时保留创建对象名称时指定的关键属性的顺序。JConsole用于构建MBean树的确切键属性列表将是ObjectName.getKeyPropertyListString()方法返回的类型,第一个键为type,第二个键为j2eeType(如果存在)。

但是,当JConsole呈现MBean树时,依赖于ObjectName关键属性的默认顺序有时会导致意外的行为。例如,如果两个对象名称具有相似的键,但键顺序不同,则相应的MBean将不会在MBean树中的同一节点下创建。

例如,假设您使用以下名称创建Triangle  MBean对象:

com.sun.example:type=Triangle,side=isosceles,name=1
com.sun.example:type=Triangle,name=2,side=isosceles
com.sun.example:type=Triangle,side=isosceles,name=3

就JMX技术而言,这些对象将以完全相同的方式处理。对象名称中键的顺序与JMX技术没有什么区别。但是,如果JConsole连接到这些MBean,并且使用默认的MBean树渲染,那么对象com.sun.example:type = Triangle,name = 2,side = isosceles将最终创建在Triangle节点下的一个节点中称为2,这又将包含一个称为isosceles的子节点。另外两个等腰三角形name = 1和name = 3将被组合在称为isosceles的不同节点的Triangle下,如图3-13所示


上一篇:在resin配置參数实现JConsole远程监控JVM


下一篇:实战 -- Redis2.4.2集成spring3.2.2