G1GC的算法与实现-算法篇
根据《深入Java虚拟机-JVM G1GC的算法与实现》-算法篇整理而来,该篇主要由以下章节组成
- 第一章 G1GC是什么?
- 第二章 并发标记
- 第三章 转移
- 第四章 软实时性
- 第五章 分代G1GC模式
- 第六章 算法篇总结
G1GC是什么?
Garbage-First (G1) 垃圾收集器是一种服务端的垃圾收集器,针对具有大内存和多处理器的机器。它尝试尽量满足用户设定的垃圾收集 (GC) 暂停时间,同时实现高吞吐量。GC操作(例如全局标记)与应用程序线程同时执行。
这是JDK官方对于G1的定义,这里作者提出一个结论G1的特点是非常非常的关注实时性,并且实时性分为软实时性/硬实时性
硬实时性指的是硬性强制要求的,如果达不到指定时间就会返回失败的处理;
软实时性指的是柔性的,对于设定的指定时间只是一个期望,不会做强制的要求限制;
额外一点是G1是支持4G以上的堆内存进行垃圾收集
G1出现的背景
在G1出现之前的GC处理器主要是通过增量GC或者是并发GC来提高STW的暂停时间,但是这样缩短时间会造成吞吐量下降。
G1的出现是为了解决在期望的暂停时间周围尽量的完成更大的GC吞吐量。目前GC的关注点都是在尽可能的减少暂停时间,而不是增大吞吐量上,这可能是因为堆中的对象大多属于是朝生夕死的类型
G1的目前的现状
G1在JDK9中就作为默认的垃圾回收器,现阶段G1在最后一次增强是在JDK14中增加对NUMA(非统一内存访问)的增强。在JDK14中新增了ZGC收集器,并且预计将ZGC在未来的JDK版本中作为默认GC
G1GC的执行过程
所有GC在执行过程可以都划分为标记和整理两个大的步骤,不同的是具体的执行过程会有差别
G1GC的标记过程
G1GC的标记过程是并发标记,但是目前的GC还做不到全局并发,只能在某些标记步骤中做到并发。G1的标记过程划分为五个步骤分别是
- 初始标记阶段
- 并发标记阶段
- 最终标记阶段
- 存活对象计数阶段
- 收尾工作
-
初始化标记阶段
初始化标记阶段只对根引用对象进行标记这个过程也称为根扫描,由于mutator(用户线程)会修改根对象引用,因此在者一步是需要将mutator暂停下来,这里之所以没有采用读/写屏障的技术来实现并发个人猜测是因为mutator会频繁修改根对象,因此在此处保证并发后的性能损耗远远大于顺序执行所带来的性能损耗。
在初始化标记阶段只会对根引用对象进行标记到特定的内存中称为标记位图 -
并发标记阶段
并发标记阶段的特点是GC线程与mutator线程是并发执行的,在mutator线程修改根对象引用时会采用写屏障来记录对象之间引用关系的变化。
SATB是记录对象之间逻辑引用关系的结构,全称为Snapshot At The Beginning(初始快照),在并发标记过程中产生的新对象会作为“已完成扫描和标记”的对象,在mutator线程发生对标记对象的修改时,SATB专用写屏障也会将该对象记录到SATB队列中。SATB队列在实现上采用与线程绑定的形式来进行,当队列装满时,将会添加到全局SATB队列中。
log
并发指的是更多的指的是软件领域的无序执行,不同任务之间没有顺序关系的一种软件启动方式并行更多的指的是在硬件领域不同指令在同一时刻执行的
参考文章
https://tech.meituan.com/2016/09/23/g1.html
https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html