CMS和G1

167 阅读3分钟

CMS

CMS是一个hotspot划时代的垃圾收集器,它是一个并发的垃圾收集器,也就是说GC线程是可以和用户线程一起运行,如图所示

未命名文件(16).png 可以看到CMS主要分为以下几个阶段:

  1. 初始化标记
  2. 并发标记
  3. 重新标记
  4. 并发清理
  5. 重置线程

对于以上阶段只有初始化标记和重新标记是STW的,其他阶段都是并发的,那么这个过程中肯定会存在一些问题,因为用户线程和GC线程是一起运行的。

1、初始化标记

这阶段只扫描跟GC-ROOTS关联的对象,这个过程很快,常见的初始化标记GC-ROOTS对象有:局部变量、常量、静态属性、JNI引用、以及跨代引用的对象

2、并发标记

这个过程是并发的所以不存在STW的问题,但是跟用户线程共存,难免有两个问题,漏标以及浮动垃圾的问题,CMS使用三色标记+增量更新处理并发标记时垃圾的问题,但是没有解决浮动垃圾的问题,因为增量更新只处理白色对象被一个黑色对象所引用,这时候会将黑色对象重置为灰色,可以认为是关注引用的增加。

3、重新标记

重新标记,这个过也是STW,但是时间也不会太长,比并发标记短多了,这个过程主要处理漏标的问题

4、并发清理

并发清理阶段也是不需要STW的,但是正是因为如此这个阶段也会产生浮动垃圾,这也是CMS使用标记-清除算法的原因,也导致了内存碎片的问题。

5、重置线程(略)

G1

因为CMS存在的问题,hotspot推出了G1,G1在回收时会优先回收效率高的,这也是名字的由来,同时支持可预测的停顿时间,当然这不能乱设置,否则会导致频繁GC,G1在物理上没有了年轻代和老年代的划分,都是一个个的region,局部采用复制算法,全局来看是采用标记-整理算法。主要分为以下几个阶段:

1.png

可以看到G1主要分为以下几个阶段:

  1. 初始化标记
  2. 并发标记
  3. 最终标记
  4. 筛选回收
  5. 重置线程 G1的流程和CMS大致相同,以下我们具体分析一下:
1、初始化标记

和CMS一致

2、并发标记

这个阶段和CMS一样也是不需要STW的,G1使用三色标记+原始快照,来解决漏标问题,SATB会在开始生成一个快照(bitmap),认为这个快照里面的对象都是存活的,后续如果引用发生了删除,会将这个引用关系,推送到GC的堆栈上,保证这个对象还能被找到,但即使这个是这对象已经是垃圾了,还是会标记为黑色,也就是说这里还是会有浮动垃圾。

3、最终标记

和CMS一致

4、筛选回收

这一步也是G1的名称的由来,它会对垃圾进行排序,优先回收效率最高,然后尽量的满足你的停顿时间,然后这个阶段是STW的所以这里不存在浮动垃圾的的问题

5、重置线程

总结

  1. CMS确实是一个划时代的产物,它是第一个并发的垃圾回收器,但是遗留了几个问题 内存碎片、浮动垃圾,如果空间不够,将会使用Serial,这时候全程STW,所以不会等到老年代空间完全使用后才进行GC。
  2. G1对CMS存在的问题进行了进一步的优化 ,解决了内存碎片以及一部分的浮动垃圾的问题