CMS垃圾回收流程的理解
初始标记:STW,标记处GC roots能直接关联到的对象速度很快
并发标记:垃圾回收线程和工作线程同时工作,遍历整个对象图,标记出可达对象
重新标记:STW,重新标记出并发标记阶段新产生的垃圾对象。(因为并发标记阶段,用户线程在运行,引用可能发生变化)
并发清理:清理垃圾,同时工作线程也会运行
CMS问题:浮动垃圾 + 内存碎片
并发清理阶段,用户线程在运行,新产生的垃圾没法清理,就会成为浮动垃圾,只能等待下一次垃圾回收进行收集
由于cms使用的是标记-清除算法,不会进行碎片整理,所以会产生内存碎片。
当碎片很多的时候,当新的对象过来的时候,可能找不到空间存放了(产生Promotion Failed),这时候会把老奶奶Serial Old请出来回收空间.
怎么解决内存碎片问题:
- -XX:+UseCMSCompactAtFullCollection
在FGC时进行压缩 ==> 解决碎片化的参数 - -XX:CMSFullGCsBeforeCompaction
多少次FGC之后进行压缩 ==> 解决碎片化的参数
这两个参数可以设置在FGC时进行压缩或者进行多少次FGC之后进行压缩。
调整–XX:CMSInitiatingOccupancyFraction,指得是当老年代的空间利用达到百分比多少的时候,进行CMS回收垃圾,让老年代有足够的空间来进行Promotion和产生浮动垃圾。
调优的时候,可以适当降低这个值,让CMS保持老年代有足够的空间,以免触发Serial Old老奶奶。