JVM调优学习之旅-(7)P+CMS模拟案例优化分析思想-每秒十万的QPS社交
模拟案例背景
|
|
用户操作
|
|
JVM
|
|
优化前参数
|
|
- -XX:+UseCMSCompactAtFullCollection -XX:CMSFullGCsBeforeCompaction=5
这个JVM参数我们应该关注一下:
对象进入老年代,由于老年代没有进行碎片整理,放不下一些大对象,就会导致更快的FGC,而这两个参数就是在5次FGC后进行整理内存碎片。JVM叫这压缩,Compaction。
所以我们年轻代优化好了,还得根据FGC的次数。看老年代在高峰期FGC的次数,来进行优化这个次数。因为这个整理碎片的过程也是会STW的。
怎么优化
通过jstat分析一下各个机器上的jvm的运行状况,判断出来每次Young GC 后存活对象有多少,然后就是合理增加Survivor区的内存,避免对象快速进入老年代。
另外一个,在当时对那个系统优化之后,增加了年轻代和Survivor区的大小,但还是会慢慢的有对象进入老年代里,毕竟系统负载很高,彻底让对象不进入老年代也很难做到。
在降低了Full GC频率之后,务必设置如下参数“-XX:+UseCMSCompactAtFullCollection - XX:CMSFullGCsBeforeCompaction=0”,每次Full GC后都整理一下内存碎片。这个可以根据高峰期FGC次数权衡。
如果不合理修改这个参数就会导致:每次Full GC过后,都造成老年代里很多内存碎片,那么必然导致下一次Full GC更快到来,因为内存碎片会导致老年代可用内 存变少。也许第一次Full GC是一小时才有,第二次Full GC也许是40分钟之后,第三次Full GC可能就是20分钟之后,要是不解决CMS内存碎片 问题,必然导致Full GC慢慢变得越来越频繁
如何尽可能优化FGC
一个参数是“-XX:+CMSParallelInitialMarkEnabled”,
这个参数会在CMS垃圾回收器的“初始标记”阶段开启多线程并发执行。 大家应该还记得初始标记阶段,是会进行Stop the World的,会导致系统停顿,所以这个阶段开启多线程并发之后,可以尽可能优化 这个阶段的性能,减少Stop the World的时间。
另外一个参数是“-XX:+CMSScavengeBeforeRemark”,
这个参数会在CMS的重新标记阶段之前,先尽量执行一次Young GC。 也就是,CMS的重新标记也是会Stop the World的,所以如果在重新标记之前,先执行一次Young GC,就会回收掉一 些年轻代里没有人引用的对象。 所以如果先提前回收掉一些对象,那么在CMS的重新标记阶段就可以少扫描一些对象,因为老年代对象可能会和年轻代有引用关系,gc roots寻找扫描的路径就变短了,此时就可以提升CMS的重新标记阶段的性能, 减少他的耗时。