压力测试下的java内存回收优化

来源:互联网 发布:软件界面修改工具 编辑:程序博客网 时间:2024/05/20 14:18

使用loadrunner,对系统进行性能测试,在经过代码优化和硬件升级后,各项指标均达到要求,但在lr里,每秒事务数、吞吐量等指标在曲线图中每隔一会就有一个不大不小的断崖(波谷),说明在这个时间段中,系统性能降低了,经过学习查找,发现问题是出在java内存回收的设置上。

我是根据这个帖子得到的启发:http://blog.csdn.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的曲线: