一、VisualVM简介
VisualVM 是一个功能强大的JVM运行监视和故障处理工具,自从 JDK 6 Update 7 以后已经作为 Oracle JDK 的一部分,位于 JDK 根目录的 bin 文件夹下。其性能分析功能甚至比起JProfiler、YourKit等专业且收费的工具都不会逊色多少。而且VisualVM还有一个很大的优点:不需要被监视的程序基于特殊Agent运行,因此它对应用程序的实际性能影响很小,使得它可以直接应用于生产环境中。这个优点是JProfiler、YourKit等工具无法与之媲美的。
使用之前可以根据需要下载安装合适的插件
1、VisualVM 插件中心安装:
主菜单中选择“工具”>“插件”。在“可用插件”标签中,选中该插件的“安装”复选框。单击“安装”。
2、手动安装:主菜单中选择“工具”>“插件”,在“已下载”标签中,点击"添加插件"按钮,选择已下载的插件文件 (.nbm) 并打开。
插件下载地址https://visualvm.java.net/pluginscenters.html
VisualVM详细使用可参考http://www.ibm.com/developerworks/cn/java/j-lo-visualvm/
二、Eclipse调优
1、未调整以前分析
Eclipse.ini中关于JVM参数的原始配置如下:
--launcher.XXMaxPermSize
256m
-Xms40m
-Xmx256m
将EclipseStartTime_1.0.0.201011281102.jar(见附件)放到plugins目录下,可以显示Eclipse启动耗时,如下图所示:
图二.1 Eclipse耗时统计插件显示
图二.2 VisualVM 的GC 情况
未优化以前Eclipse启动分析如下:
■整个启动过程平均耗时约13秒。
■垃圾收集总耗时3.177秒 ,其中
Full GC被触发了12次,耗时2.942秒;
Minor GC触发36次,耗时0.235秒。
■加载类9663个,共耗时11.229秒
■虚拟机256MB( -Xmx256m)堆内存分配170.688MB给老年代(Old Gen),85.312MB给新生代(68.312MB给Eden,两个Surviver分别为8.5MB)。
2、参数调整分析
新生代Minor GC频繁,是由于虚拟机分配给新生代的空间太小而导致的,有必要使用-Xmn参数调整。
12次的Full GC大约耗时3秒,占了大部分的GC时间,降低GC时间的主要目标就是降低这部分时间。通过查看GC日志分析(-XX:+PrintGCDetails 打印GC详细信息 -Xloggc:mygc.log 位于eclipse.exe同目录下)
7.487: [Full GC 7.487: [Tenured: 18826K->20090K(27328K), 0.1591992 secs] 22161K->20090K(39680K), [Perm : 20479K->20479K(20480K)], 0.1593305 secs] [Times: user=0.16 sys=0.00, real=0.16 secs]
8.532: [Full GC 8.532: [Tenured: 20781K->23470K(33484K), 0.1794857 secs] 31767K->23470K(48588K), [Perm : 24575K->24575K(24576K)], 0.1796180 secs] [Times: user=0.19 sys=0.00, real=0.19 secs]
9.280: [Full GC 9.280: [Tenured: 23470K->25873K(39120K), 0.2306239 secs] 30999K->25873K(56784K), [Perm : 28671K->28651K(28672K)], 0.2307639 secs] [Times: user=0.25 sys=0.00, real=0.25 secs]
10.717: [Full GC 10.717: [Tenured: 26054K->28920K(43124K), 0.2285320 secs] 33607K->28920K(62644K), [Perm : 32767K->32767K(32768K)], 0.2286774 secs] [Times: user=0.22 sys=0.02, real=0.23 secs]
括号中的红色数字代表老年代容量,这组GC 日志显示是老年代的空间耗尽,每发生一次Full GC都伴随着一次老年代空间扩容:27328K-> 33484K-> 39120K->43124K。
通过分析可知:Eclipse启动时的Full GC 大多数是由于老年代扩容导致的,由永久代(Perm )扩容导致的也有一部分。为了避免这些扩容所带来的性能浪费,可以把-Xms和-XX:PermSize参数分别设置为-Xmx和-XX:PermSizeMax参数值,强迫虚拟机在启动的时候就把老年代和永久代容量固定下来,避免运行时自动扩展。
eclipse.ini 中jvm参数为
-Xmx512m
-Xms512m
-Xmn256m
-XX:PermSize=96m
-XX:MaxPermSize=96m
使用这个配置之后GC次数已经大幅降低,启动时间变为10秒左右。
3、其他
在有些情况下,Old Gen曲线一直平滑,但还是发生Full GC。
此时用 jstat -gccause 进程号 命令查询一下最近一次GC的原因。有可能是代码调用了System.gc(),显式触发了GC。在内存设置调整后,这种GC不符合我们的期望。因此在eclipse.ini中加入-XX:+DisableExplicitGC参数屏蔽掉System.gc()。
C:\Documents and Settings\Administrator>jps
2016 Jps
10008
C:\Documents and Settings\Administrator>jstat -gccause 10008
S0 S1 E O P YGC YGCT FGC FGCT GCT LGCC GCC
0.00 0.00 29.19 13.70 41.11 4 0.328 1 0.408 0.735 System.gc() No GC