日常记录——JVM—G1垃圾回收器

一、简介、

G1垃圾回收器(Garbage First):是当今垃圾回收技术最前沿的成果之一,在17年作为JDK9默认的垃圾处理器。是一个可控的STW时间垃圾回收器,通过-XX:MaxGCPauseMillis 设置预期STW最大时间,G1会尽量达成目的,但不一定达成。

二、原理

G1垃圾回收器逻辑上存在年轻代、年老代之分,但实际在内存分配上将内存分成一小块一小块的Region,每个Region在某一时刻代表年老区(O),伊甸区(E),幸存区(S),大对象区(H,属于年老代,一个对象超过一半区域就放入H区),但回收过后可能用来代表其他区,较为灵活。
日常记录——JVM—G1垃圾回收器_第1张图片
CSet:GC过程记录可回收Region的集合。可回收Region中存活对象复制到另一个可用分区,然后将当前可回收Region清空。CSet中的分区可以来自eden空间、survivor空间、或者老年代。
RSet:当Region1的引用Region2的对象时,Region2的RSet就会记录对应引用关系,作用是不需要扫描整个堆找到谁引用了当前分区中的对象,只需要扫描RSet即可。但会占用内存,空间换时间。
G1回收时计算出每个区域回收所获得的空间以及所需时间的经验值,根据值区回收最值得回收的区域。G1可以根据情况动态的调整各种Region的数量,不再回收整个堆,而是估计每个Region中的垃圾比例,优先回收垃圾多的Region。这就为什么被叫做Garbage First算法。这也是为什么G1可以控制STW停顿时间的原因。
每个Region中分为很多小块,每个区域我们成为Card,每个Card有多个对象组成。当对应的内存空间发生改变时,就会标记为dirty,将Card存入Dirty Card Queue。
Young GC:Eden区不足触发,会造成STW,但很短暂。
1.可达分析GCRoot。
2.更新RSet,处理dDirty Card Queue更新RS。
3.处理RSet,存活对象。
4.存活对象复制。
5.清理。
6.记录时间,调整Region数量。
Mixed GC:达到InitatingHeapOccpancyPercent触发,短暂STW。
1.初始标记,标记了从GCRoot直接可达的对象,并发标记,短暂STW。
2.根区域扫描:在初始标记的存活区扫描对老年代的引用,并标记被引用的对象到RSet。该阶段与用户线程并发。该阶段完成,才能开始下一次 STW 年轻代垃圾回收。
3.并发标记:在整个堆中查找存活对象,使用三色标记算法,与用户线程并发。可以被 STW 年轻代垃圾回收中断
4.重新标记:使用STAB标记被修改引用的对象。并发标记,短暂STW。
5.筛选清除垃圾:清理最大垃圾,记录时间,调整Region大小。
Full GC:G1的GC过程会在Young GC和Mixed GC之间不断地切换运行,但如果仍有对象分配不了内存,将触发Full GC,使用Serial GC,STW时间较长。可通过-XX:InitatingHeapOccpancyPercent设置触发Mixed GC内存占比,降低Full GC触发几率,默认45%。

三、三色标记算法

无论CMS或者G1在并发标记过程中使用的都是三色标记算法,标记时将对象在逻辑上分为3种颜色:
黑色:当前对象和其子成员变量都被标记过。
灰色:当前对象标记过,当成员变量未标记过。
白色:未被标记的对象。
日常记录——JVM—G1垃圾回收器_第2张图片
回收时可通过标记颜色,确定对象是否为可回收对象。
问题:因为该算法在并发标记中使用,可能会产生在标记过程中,对象引用关系发生改变。
日常记录——JVM—G1垃圾回收器_第3张图片
可能会产生如上情况,黑色对象的引用指向了白色对象,并且灰色对象与白色的引用关系解除,就会造成C对象漏标的情况,灰色对象B需要继续扫描白色C的引用解除,黑色对象A是成员变量标记完。
为了处理这种情况CMS和G1分别采用下面两种方式处理:
Increment Update:增量更新,当黑色对象引用指向白色对象时,将黑色对象更新为灰色对象,将继续扫描灰色对象的成员变量。CMS采用该处理方式。
STAB:snapshot at the beginning,开始快照,当灰色对象引用和白色对象解除时,将该引用关系存储到GC线程栈中,重新标记时,扫描栈中该引用关系,可找到白色对象。G1采用该处理方式。

STAB相较与Increment Update只在线程栈中存储了引用,便定位到漏标对象,而Increment Update会重新扫描一遍更新后的灰色对象,如果灰色对象的成员变量很多,但只有一个漏标,就会浪费很多时间,并且STAB存储的引用可以和Rset结合使用,增快GC效率。

四、扩展

ZGC:Java 11 新垃圾回收器 ZGC。一个回收时间最高10MS的垃圾回收器,用户感觉不到停顿。堆管理容量范围(小M级别,大到T级别)。无分代逻辑。使用颜色指针,在引用中使用3个byte存储引用状态。开启参数:-XX:+UseZGC。

你可能感兴趣的:(JVM)