上海盛大网络发展有限公司 |
VisualVM使用手册 |
|
徐景春 2011-4-2
|
目 录
1. Visual VM基本信息
VisualVM是JDK的一个集成的分析工具,自从JDK 6 Update 7以后已经作为Sun的JDK的一部分。
VisualVM可以做的:监控应用程序的性能和内存占用情况、监控应用程序的线程、进行线程转储(Thread Dump)或堆转储(Heap Dump)、跟踪内存泄漏、监控垃圾回收器、执行内存和CPU分析,保存快照以便脱机分析应用程序;同时它还支持在MBeans上进行浏览和操作。尽管 VisualVM自身要在JDK6以上的运行,但是JDK1.4以上版本的程序它都能被它监控。
界面
2. Visual VM的安装
Step1.从官网http://visualvm.java.net/下载VisualVM安装程序,有英文版与多语言版(包括中文)
Step2.需要在本机安装jdk 6以上jdk版本
Step3.解压缩VisualVM压缩包后,至bin目录下,打开visualvm.exe即可运行
3. 远程监控连接方式
以下以监控Jboss应用为例,VisualVM有两种方式监控,为JMX方式和Jstatd方式。
3.1JMX方式连接
Step1. 添加Jboss启动参数,开启监控端口
A. 修改JDK中jmx配置文件方法:
切换至$JAVA_HOME所在目录/jre/lib/management下,
将jmxremote.access、jmxremote.password.template权限调整为读写:
#cpjmxremote.password.template jmxremote.password
#chmod600 jmxremote.password
#chmod600 jmxremote.access
vi jmxremote.password去掉
# monitorRole QED
# controlRole R&D 前面的#号
B. 在Jboss的启动文件中添加以下信息:
JAVA_OPTS="-Dcom.sun.management.jmxremote.port=8889 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Djava.rmi.server.hostname=<服务器IP> "
例如:
Export JAVA_OPTS="$JAVA_OPTS
-Djava.rmi.server.hostname=10.132.81.31
-Dcom.sun.management.jmxremote.port=8889
-Dcom.sun.management.jmxremote.ssl=false-Dcom.sun.management.jmxremote.authenticate=false "
C. 检查启动情况:
netstat -a | grep -i 8889 查看端口占有情况
如果8889端口被其他程序占用,在jboss配置文件中调整端口-Dcom.sun.management.jmxremote.port=****
Step2. VisualVM中添加JMX端口
在远程上右键,点击[添加远程主机],输入被监控的服务器IP
在已添加的服务器标签上点击右键,选择[添加JMX连接],输入之前在Jboss中添加的远程端口如8889,显示名称可自定义,点击确定。
JMX方式添加成功。
注意:
如果要远程监控服务器,必须要修改服务器Hosts中Localhost地址为本机对外IP或者在Jboss启动参数中添加-Djava.rmi.server.hostname=<服务器IP>,否则会出现无法用JMX连接。
3.2Jstatd方式连接
Step1. 启动Jstatd
Cd$JAVA_HOME/bin目录下
用vi新建一个jstatd.all.policy文件,在里面添加以下内容来保证jstatd服务启动的时候不报异常:
grant codebase"file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
netstat -ano| grep -i 1099 查看1099端口是否被占用了,如果被占用,则需要选择其他端口来启动jstatd服务
如果端口被占用,用以下方式启动jstatd服务:
rmiregistry2020 & jstatd -J-Djava.security.policy=jstatd.all.policy -p 2020 (需要后台启动,否则退出后命令失效)
将Jstatd绑定到2020端口
后台启动:
nohup jstatd-J-Djava.security.policy=jstatd.all.policy-J-Djava.rmi.server.hostname=10.132.81.17
-J-Dcom.sun.management.jmxremote.ssl=false-J-Dcom.sun.management.jmxremote.authenticate=false &
备注:
与添加Jboss启动命令相同,如果Hosts中未更改Localhost对应本机IP,则需要添加参数-J-Djava.rmi.server.hostname=<服务器IP>
Step2. 添加Jstatd连接
在远程服务器IP上点击右键,选择[添加jstatd连接]
在属性中,可以看到已添加Jstatd默认端口1099,也可以点击添加定制输入指定端口(如2020端口),确定。
Jstatd添加完成后,可自动显示该服务器上的应用如图(Jstatd会通过进程号监控应用)
4. VisualVM监控内容介绍
下面以监控JBoss为例,介绍下用VisualVM监控JVM内存情况。
由于PE81.17为通过JMX方式连接到JBoss,JBoss(pid 19268)为Jstatd方式连接,因此两个标签实际上为同一个Jboss应用,实际应用中两种连接方式可选其一。
概述
在概述标签中,描述了该应用的类型,进程号,IP地址,JVM内存大小设置情况,以及启动参数等,也可看到应用路径,如:
webapp.root=/home/peuser/pe/run/jboss/./tmp/deploy/tmp61754843639786460pe-1.0-SNAPSHOT-exp.war
监控总览
JVM内容总览,可从上图各图形中看到当前CPU、堆栈、PerGen空间使用以及对象和线程的活动情况。
如果PerGen不断增加,超过JVM中设置的PerGen Size,可能会导致内存溢出情况。
可手工执行垃圾回收,测试程序垃圾回收是否正常,也可执行堆Dump(heapdump),远程监控默认保存为服务器/tmp/heapdump-****.hprof文件,若为本地JVM监控,可直接显示结果。如下图:
线程监控
此标签下可以跟踪线程状况。
线程状态
可以监控各个线程运行情况(此处监视可能翻译有误,应为Block阻塞进程)
点击线程dump,可以生成该线程的运行情况的thread dump文件,通过thread dump提供的相关信息,我们可以看到线程在什么地方被阻塞了以及线程的其他状态。
与图表对应的具体数值
另一种显示形式,线程不同状态所占时间比例。
抽样器介绍
CPU抽样
可以看到当前方法所占用的CPU情况
内存采样
可以看到当前方法所占用的内存情况
Visual GC监控
下图有点类似于Jconsole监控
GCJAVA的垃圾回收机制,可以根据这个图表来判断程序是否会出现内存泄露或溢出。
内存申请过程:
A.JVM会试图为相关Java对象在Eden中初始化一块内存区域
B.当Eden空间足够时,内存申请结束。否则到下一步
C.JVM试图释放在Eden中所有不活跃的对象(这属于1或更高级的JVM垃圾回收);释放后若Eden空间仍然不足以放入新对象,则试图将部Eden中活跃对象放入Survivor区/OLD区
D.Survivor区被用来作为Eden及OLD的中间交换区域,当OLD区空间足够时,Survivor区的对象会被移到Old区,否则会被保留在Survivor区
E.当OLD区空间不够时,JVM会在OLD区进行完全的垃圾收集(0级)
F.完全垃圾收集后,若Survivor及OLD区仍然无法存放从Eden复制过来的部分对象,导致JVM无法在Eden区为新对象创建内存区域,则出现"outofmemory错误"。
从内存申请过程来看,若Old区域堆满后,会出现内存溢出。