步骤
初始标记<br>
暂停所有的其他线程STW,并记录下gc root 直接引用的对象,速度很快<br>
并发标记<br>
从GC Roots的直接关联对象开始遍历整个对象图的过程, 这个过程耗时较长但是不需要停顿用户线程
过程不用停顿其他的用户线程,提高用户体验<br>
因为用户程序继续运行,可能会有导致已经标记过的对象状态发生改变。
重新标记<br>
三色标记<br>
修复并发标记阶段中因为用户线程继续运行而导致标记变动的的部分记录<br>
会STW
并发清理<br>
开启用户线程,同时GC 线程开始对未标记的区域做清扫,如果这个阶段新增对象会标记为黑色不作任何处理
缺点
对CPU资源敏感(会和服务抢资源)<br>
无法处理浮动垃圾<br>
浮动垃圾:在并发标记和并发清理阶段又产生垃圾
因为gc 线程和用户线程一起执行就会产生互动垃圾
只能等待下次gc才能清理
标记-清除算法会导致收集结束时会有大量空间碎片产生<br>
concurrent mode failure<br>
在并发标记和并发清理阶段会出现,一边回收,系统一边运行
也许没回收完就再次触发full gc,就会产生此情况
此时会进入stop the world,用serial old垃圾收集器来回收
核心参数
-X 与 -XX区别X 越多 将来的版本可能约不支持,越不稳定
-XX:+UseConcMarkSweepGC:启用cms
-XX:ConcGCThreads:并发的GC线程数
-XX:+UseCMSCompactAtFullCollection:FullGC之后做压缩整理(减少碎片)
-XX:CMSFullGCsBeforeCompaction:多少次FullGC之后压缩一次,默认是0,代表每次FullGC后都会压缩一次
可以避免concurrent mode failure
-XX:+UseCMSInitiatingOccupancyOnly:只使用设定的回收阈值(-XX:CMSInitiatingOccupancyFraction设定的值),如果不指定,JVM仅在第一次使用设定值,后续则会自动调整
-XX:+CMSScavengeBeforeRemark:在CMS GC前启动一次minor gc,目的在于减少老年代对年轻代的引用,降低CMS GC的标记阶段时的开销,一般CMS的GC耗时 80%都在标记阶段
减少跨代的引用
-XX:+CMSParallellnitialMarkEnabled:表示在初始标记的时候多线程执行,缩短STW
-XX:+CMSParallelRemarkEnabled:在重新标记的时候多线程执行,缩短STW;