JVM关于CMS和G1垃圾回收器总结

180 阅读2分钟

CMS

image.png

1.使用的是标记清除算法,对老年代的回收器

2.初始标记,标记的是GC Roots的对象,会STW,时间很短

3.并发标记是进行标记GC ROOTS关联的对象,时间可能比较长,但是不影响用户线程使用

4.重新标记是对并发标记的补充,因为并发标记阶段,用户程序还在运行,其实是个修正过程。

5.并发清理,直接多线程清理掉不在GC ROOTS的对象,回收结束

总结:
缺点:
1.使用标记清除算法可以不移动对象,从而不影响用户线程运行

2.会产生内存碎片,一般会有searlOld兜底,进行一次整理

3.清理不干净,有浮动垃圾

优点:停顿时间短,强调低延迟

G1

image.png

1.使用的标记整理+复制算法,对整个堆空间进行回收

2.当年轻代也就是E区内存紧张情况下会进行一次Young GC,把所有年轻代的Region对象使用复制算法拷贝新的S区,S区达到一定年龄,拷贝到O区

3.当老年代也就是O区达到一定阈值,-XX:InitiatingHeapOccupancyPercent(老年代占堆比例)达到了设定的比例,就会进行Mixed GC,对年轻代进行2步骤进行回收,对老年代不会全部回收,根据设置的-XX:MaxGCPauseMillis估算STW时间,来进行回收对应的O区间,从而达到控制STW时间的效果

4.当发现分配新region内存不足时候,可能是内存碎片导致,可能是大对象(大于region的对象)无法分配,这个时候就会进行Full Gc,进行对整个堆的规整,使用标记整理算法。

总结

1.两款垃圾回收器都是为了降低STW

2.CMS控制整个STW的时间是整个老年代,G1控制STW时间是region级别的,明显G1控制更精准。当然这也是G1最大的特性,都是分region,不是操作整个新生代/老年代

3.CMS只负责收集老年代收集,G1负责整个堆空间收集

4.CMS和G1控制STW时间都是只对老年代做了处理,其实大家可以想想为什么?可以留言(笔者认为,因为年轻代对象很少影响用户线程执行基本上是每个线程自己new的数据,老年代基本上是所有线程都经常依赖的对象)