文章

jvm垃圾回收器-ZGC

ZGC

ZGC 是一种可扩展的低延迟垃圾回收器。ZGC 在垃圾回收过程中,STW的时间不会超过一毫秒,适合需要低延迟的应用。支持几百兆到16TB 的堆大小,堆大小对STW的时间基本没有影响。

在G1垃圾回收器中,STW时间的主要来源是在转移阶段:

1、初始标记,STW,采用三色标记法标记从GC Root可直达的对象。 STW时间极短

2、并发标记,并发执行,对存活对象进行标记。

3、最终标记,STW,处理SATB相关的对象标记。 STW时间极短

4、清理,STW,如果区域中没有任何存活对象就直接清理。 STW时间极短

5、转移,将存活对象复制到别的区域。 STW时间较长

ZGC执行流程

image-20240918171718101

G1转移时需要停顿的主要原因

在转移时,能不能让用户线程和GC线程同时工作呢?考虑下面的问题:

转移完之后,需要将A对对象的引用更改为新对象的引用。但是在更改前,执行A.c.count = 2,此时更改的是

转移前对象中的属性

image-20240918172519942

更改引用之后, A引用了转移之后的对象,此时获取A.c.count发现属性值依然是1。这样就产生了问题,所以G1

为了解决问题,在转移过程中需要进行用户线程的停止。ZGC和Shenandoah解决了这个问题,让转移过程也

能够并发执行。

ZGC的解决方案

在ZGC中,使用了读屏障Load Barrier技术,来实现转移后对象的获取。当获取一个对象引用时,会触发读后的

屏障指令,如果对象指向的不是转移后的对象,用户线程会将引用指向转移后的对象。

image-20240918172752375

读屏障指令,在获取一个对象引用时,用户线程会将引用指向转移后的对象。

着色指针(Colored Pointers)

访问对象引用时,使用的是对象的地址。在64位虚拟机中,是8个字节可以表示接近无限的内存空间。所以一般

内存中对象,高几位都是0没有使用。着色指针就是利用了这多余的几位,存储了状态信息。

image-20240918215844204

着色指针(Colored Pointers)

着色指针将原来的8字节保存地址的指针拆分成了三部分:

  1. 最低的44位,用于表示对象的地址,所以最多能表示16TB的内存空间。
  2. 中间4位是颜色位,每一位只能存放0或者1,并且同一时间只有其中一位是1。
  • 终结位:只能通过终结器访问
  • 重映射位(Remap):转移完之后,对象的引用关系已经完成变更。
  • Marked0和Marked1:标记可达对象

​ 3、16位未使用

image-20240918220042820

正常应用程序使用8个字节去进行对象的访问,现在只使用了44位,不会产生问题吗?

应用程序使用的对象地址,只是虚拟内存,操作系统会将虚拟内存转换成物理内存。而ZGC通过操作系统更改

了这层逻辑。所以不管颜色位变成多少,指针指向的都是同一个对象。

image-20240918220121933

ZGC的内存划分

在ZGC中,与G1垃圾回收器一样将堆内存划分成很多个区域,这些内存区域被称之为Zpage。

Zpage分成三类大中小,管控粒度比G1更细,这样更容易去控制停顿时间。

小区域:2M,只能保存256KB内的对象。

中区域:32M,保存256KB – 4M的对象。

大区域:只保存一个大于4M的对象。

License:  CC BY 4.0