压力测试下的java内存回收优化
使用loadrunner,对系统进行性能测试,在经过代码优化和硬件升级后,各项指标均达到要求,但在lr里,每秒事务数、吞吐量等指标在曲线图中每隔一会就有一个不大不小的断崖(波谷),说明在这个时间段中,系统性能降低了,经过学习查找,发现问题是出在java内存回收的设置上。
我是根据这个帖子得到的启发:http://blog.****.net/fxtt1040/article/details/6782829
起初是这样,我设置了4G的堆内存,通过jconsole可以看到,在lr运行时,堆内存会从最低点慢慢升到设置的最高点上,随后就瞬间降到最低点,反复这个过程,而瞬间下降的过程就是lr出现断崖的时候,问题就定位出现在堆内存的瞬间释放上。
抱歉,当时这块没有截图,不过还有一种情况,jconsole的类、堆内存、线程数都出现了瞬间跌落到底,有点像是系统宕机,但不一会又恢复了
依然是通过jconsole,观察,堆内存中年轻代的内存回收后,多数直接进入了年老代,而年老代的内存一释放,就出现了瞬间跌落,看来年轻代到年老代的内存回收机制是解决问题的关键。。。
我们的中间件用的是tomcat,在此之前我们设置的catalina是这样的:
JAVA_OPTS="-server -Xss256k -Xmn512m -Xms4096m -Xmx4096m -XX:PermSize=128m -XX:MaxPermSize=1024m \
-XX:ParallelGCThreads=4 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:MaxTenuringThreshold=0 \
-Dcom.sun.management.jmxremote.port=10002 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \
-Djava.util.logging.config.file=%CATALINA_BASE\conf\logging.properties"
还是对那个帖子的学习后,将设置改成了这样:
JAVA_OPTS="-server -Xss128k -Xmn1024m -Xms6144m -Xmx6144m -XX:PermSize=128m -XX:MaxPermSize=1024m \
-XX:ParallelGCThreads=16 -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:MaxTenuringThreshold=2 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=5 -XX:MaxGCPauseMillis=100 -XX:+UseAdaptiveSizePolicy \
-Dcom.sun.management.jmxremote.port=10002 \
-Dcom.sun.management.jmxremote.ssl=false \
-Dcom.sun.management.jmxremote.authenticate=false \
-Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager \
-Djava.util.logging.config.file=%CATALINA_BASE\conf\logging.properties"
再上lr后,观察jconsole的曲线:
这回曲线正常了,因为我设置了CMSFullGCsBeforeCompaction=5,所以基本不会有垃圾回收到年老代,这样年老代的内存保持了良好的状态,整个堆内存也就不会出现大起大落的情况了,在内存单项指标中,也能看到年轻代的内存一直在迭代更新,年老代的内存保持常青。
再看lr的曲线: