3.7 JVM调优
在第2.5 节介绍了JVM性能监控,本节介绍一下JVM调优[29]。
(1)配置jstatd的远程RMI服务。
如果要看远程服务器上Java程序的GC情况需要执行这个步骤,允许JVM工具查看JVM使用情况。
将下面的代码存为文件jstatd.all.policy,放到%JAVA_HOME%/bin目录下,其内容如下。
grant codebase"file:${java.home}/../lib/tools.jar" {
permission java.security.AllPermission;
};
执行命令。
>jstatd-J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.hostname=192.168.0.12&
192.168.0.12为服务器的IP地址。
(2)jVisualVM控制台
执行%JAVA_HOME%\bin\jvisualvm.exe,打开JVM控制台。通过菜单“工具->插件”中找到Visual GC插件进行安装。
(3)对要执行Java程序进行调优
以my.jar为例,在该jar包所在目录下建立一个start.sh文件,文件内容如下。
java -server -Xms4G -Xmx4G -Xmn2G -XX:SurvivorRatio=1-XX:+UseConcMarkSweepGC -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.port=1100-Dcom.sun.management.jmxremote.authenticate=false-Dcom.sun.management.jmxremote.ssl=false -jar my.jar&
配置后,使用JVM控制台即可查看JVM(CPU/内存)及垃圾回收的状况。
(4) 控制台配置
打开\jvisualvm.exe,通过菜单“远程->添加远程主机->输入远程IP->添加JMX连接”。
(5)JVM调优核心为调整年轻代、老年代的内存空间大小以及使用GC的类型。在start.sh文件内容。
首先确认这台机器是一个4G内存的机器。
•-Xms4G指JVM启动时整个堆(包括年轻代,年老代)的初始化大小。
•-Xmx4G指JVM启动时整个堆的最大值。
•-Xmn2G指年轻代的空间大小,剩下的是年老代的空间。
•-XX:SurvivorRatio=1是指年轻代空间的2个Survivor空间与Eden空间的大小比例。
官方通过增大Eden区的大小,来减少YGC发生的次数,有时虽然次数减少了,但Eden区满的时候,由于占用的空间较大,导致释放缓慢,此时stop-the-world的时间较长,所以需要按照程序实际情况去调优。
•-XX:+UseConcMarkSweepGC指使用GC的回收类型。这里是CMS类型,JDK1.7以后推荐使用+UseG1GC,被称为G1类型(或GarbageFirst)的回收器。
(6)当设定start.sh的参数值完毕后,执行./start.sh此时就可以启动了。
通过jvisualvm.exe中的Visual GC插件查看GC的图形,也可以在服务器上执行:jstat -gc <JID> 1000,看到每1秒钟Java进程号JID的GC回收情况。
# jstat -gc 15016 1000
S0C S1C S0U S1U EC EU OC OU PC PU YGC YGCT FGCFGCT GCT
699008.0 699008.0 29980.4 0.0 699136.0 116881.62097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272
699008.0 699008.0 29980.4 0.0 699136.0 118344.82097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272
699008.0 699008.0 29980.4 0.0 699136.0 119895.52097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272
699008.0 699008.0 29980.4 0.0 699136.0 121383.12097152.0 660769.4 21248.0 20071.0 354 54.272 0 0.000 54.272
••S0C。
Survivor0区分配空间。
•S0U。
Survivor1区中已经使用的空间。
•EC。
Eden区中所使用的空间。
•EU。
Eden区的当前使用空间。
•OC。
老年代分配的空间。
•OU。
老年代当前使用的空间。
•PC。
持久代的分配的空间。
•PU。
持久代的当前使用的空间。
•YGC。
年轻代发送的次数。
•YGCT。
年轻代发送的总时长。因此每次年轻代发生GC,即平均每次stop-the-world的时长为YGCT/ YGC ,单位为秒。
FGC。
年老代回收的次数,或者成为FullGC的次数。
FGCT。
年老代发生回收的总时长。
GCT。
包括年轻代YGC及年老代FGC的总时间长。
通常结合图形或数据,可以看到当EU即将等于EC的时候,会发生YGC,所以YGC次数+1,YGCT时间会增加。
当发生YGC的时候,如果S0U或S1U区如果有任意一个区域为0的时候,此时YGC的速度很快,相反如果S0U或者S1U中都有数据,或相对满的时候,此时YGC的时间偏长,这就是因为S0/S1及Eden区的比例问题导致的。
(7)经过一定时间的调优,基本上可以使得YGC的次数非常少,时间非常快,很长时间,数天都不会发生FGC,JVM调优结束。