欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

关于GC(下):CMS和G1GC的比较

程序员文章站 2022-05-15 22:30:27
简称 STW —— Stop the World,暂停所有在执行的线程 简史 2004年Sun实验室第一次发表G1论文 JDK6U14中第一次作为实验选项引入 JDK7中开始作为替换CMS的方案 JDK9中成为默认的垃圾回收器 JDK10优化,将其fullGC改为并行: "JEP307" JDK11 ......

简称

  • stw —— stop the world,暂停所有在执行的线程

简史

  • 2004年sun实验室第一次发表g1论文
  • jdk6u14中第一次作为实验选项引入
  • jdk7中开始作为替换cms的方案
  • jdk9中成为默认的垃圾回收器
  • jdk10优化,将其fullgc改为并行: jep307
  • jdk11引入了更新的zgc,可能会成为g1的潜在替代者

g1特有数据结构和算法

region

堆仍然有新生代(eden、survivor)、老年代的划分,但是不再要求它们是内存连续的。每个区都由多个region组成。
部分老年代region存储humongous对象(即下图的h),这种对象大小大于等于region的一半。
关于GC(下):CMS和G1GC的比较

(图片来源-java hotspot g1 gc的一些关键技术)

satb算法

全称snapshot-at-the-beginning,起始时活对象的快照。在理解satb前需要先了解以下知识。

三色标记法

cms和g1的算法都是通过对gc root 进行遍历,并进行三色标记。标记规则为

  • 黑色(black): 节点被遍历完成,而且子节点都遍历完成。
  • 灰色(gray): 当前正在遍历的节点,而且子节点(即对象的域)还没有遍历。遍历完所有子节点后,将成为黑色
  • 白色(white): 还没有遍历到的节点,即灰色节点的子节点。扫描结束仍是白色时会被回收。

并发扫描时,对于白色有两种情况同时发生时,可能会漏标导致被误回收:

  • 增加了被黑色引用的关系。
  • 被灰色下应用,删除了到它的引用

具体执行过程:

按照r大的说法:cms的incremental update设计使得它在remark阶段必须重新扫描所有线程栈和整个young gen作为root;g1的satb设计在remark阶段则只需要扫描剩下的satb_mark_queue。

rset

全称remember set,记录一个region里的对象被哪些其他region引用。
相对应地,有另一种辅助数据结构collection set(cset),它记录了gc要收集的region集合。gc时只需扫描cset中各个rset即可。

关于GC(下):CMS和G1GC的比较
(tips for tuning the garbage first garbage collector)

更详细的访问机制和回收过程这里不再展开,有兴趣可以参考后文引用文献。

pause prediction model

暂停预测模型,g1根据它计算出的历史数据来预测本次收集需要选择的region数量,从而尽量满足用户设定的目标停顿时间。
具体算法和公式略,可见java hotspot g1 gc的一些关键技术

垃圾回收过程

关于GC(下):CMS和G1GC的比较
分为以下几步:

  • 初始标记(initial mark)—— 标记gc root能直接关联的对象(短暂stw)
  • 并发标记(concurrent mark)—— gcrootstracing,从并发标记中的root遍历,对不可达的对象进行标记,耗时长但可并行
  • 最终标记(final remark)—— 收集并发标记期间产生的新垃圾(短暂stw),采用了satb算法比cms更快
  • 筛选回收(live data counting and evacuation)—— 对各个region的回收性价比排序,在保证时间可控的情况下清除失活对象,清除remember sets

作为对比,cms的回收过程
关于GC(下):CMS和G1GC的比较

  • 初始标记(cms initial mark)—— 标记gc root能直接关联的对象(短暂stw)
  • 并发标记(cms concurrent mark)—— gcrootstracing,从并发标记中的root遍历,对不可达的对象进行标记
  • 重新标记(cms remark)—— 修正并发标记期间因为用户操作导致标记发生变更的对象,有stw
  • 并发清除(cms concurrent sweep)

与cms相比的优势

  1. 并发度更高,充分利用cpu多线程 —— cms对cpu资源敏感,需要占用25%的线程,如果核数小于4更会占用一半的资源。
  2. 整体上是标记-整理(分代),局部是复制(分region),运行期不产生碎片 —— cms是标记-清除,会产生空间碎片和本次回收期间产生导致本次无法回收的浮动垃圾
  3. 可预测的停顿(基于region)

参考资料

  1. 周志明.著 《深入理解java虚拟机》
    2.java hotspot g1 gc的一些关键技术
    3.cms和g1的回收过程
  2. 可能是最全面的g1学习笔记
    5.g1 satb和incremental update算法的理解