GC的实践 - 响应时间优先

前段时间在公司进行了GC的调优实践,记录一下供以后参考。基本上,和网上其他人提供的配置都差不多。

 

调优前情况:

 

采用并行收集器,系统TPS约600,为每隔15分钟左右会产生一次FullGC,FullGC的时间大约15秒,FullGC期间系统无法接收任何响应,操作系统的CPU使用率下降到5%一下(平时大约30%-40%)。

 

调整前JVM参数:

-server -D_Offline_FileDataArchive=true -Xms512m -Xmx2048m -Xss256k -XX:MaxPermSize=256m -XX:+UseParallelGC -XX:+UseParallelOldGC -XX:ParallelGCThreads=4 -XX:SurvivorRatio=16

 

调试过程:

1. 添加JVM参数,打开GC的log,发现-Xms设置为512m是比较合适的。
JVM参数:

-Xloggc:traf_gc.log -verbose:gc -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintGCTimeStamps

 

2.采用并发收集器,替代并行收集器,继续设置-Xms为512m

JVM参数:

-XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled -Xnoclassgc

3. 发现时不时会在Old代GC时,系统会停止操作,无法接收任何响应,就像采用并行收集器的FullGC现象,gc的日志里显示“promotion failed”。原来是Old代在进行GC时,GC的收集速度小于Old的增加速度,导致系统彻底暂停下来,进行FullGC。

JVM参数:

-XX:CMSInitiatingOccupancyFraction=80

 

4. 发现PermGen的增长特别快,而且GC后,PermGen还在缓慢增加,最终导致PermGen爆满,系统停止运行。究其原因,是因为添加了-Xnoclassgc。 这个-Xnoclassgc是表示不多class进行垃圾回收,原本考虑class一旦load起来了,是很少会被回收的,但这只是自己毫无根据的假设。实际上,因为我们的代码里用到了Spring,hibernate,这些框架用到了很多反射,产生了大量临时的class,所以系统需要对class进行垃圾回收,-Xnoclassgc是绝不能打开的。

JVM参数:

-Xnoclassgc

 

调整后情况:

 

系统运行了3天,没有出现停机FullGC的现象,TPS提高倒不多大概到650左右。

 

调整后JVM参数:

-server -D_Offline_FileDataArchive=true -Xms2048m -Xmx2048m -Xmn512m -Xss256k -XX:MaxPermSize=256m -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:+CMSPermGenSweepingEnabled -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=6 -XX:MaxTenuringThreshold=7 -XX:CMSInitiatingOccupancyFraction=80 -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=0 -XX:SoftRefLRUPolicyMSPerMB=0

 

关于GC分代垃圾回收过程的演示,JavaEve上找到一个很好的文章

http://chenchendefeng.iteye.com/blog/455883

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值