JVM垃圾收集器之ZGC

124 阅读3分钟

「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」。

ZGC简介

ZGC是一个低延迟垃圾收集器,其和Shenandoah的目标是高度相似的,都是为了实现垃圾收集的停顿时间不超过十毫秒

其是基于Region内存布局,以低延迟为首要目标并使用了读屏障染色指针内存多重映射等技术来实现的可并发标记-整理算法的一款垃圾收集器。

内存布局

ZGC和G1以及Shenandoah一样也是基于Region的内存布局,不过ZGC的Region布局具有动态性(动态创建与销毁以及动态的区域容量大小)。

ZGC中Region分为大中小三类。

  • 大型Region:容量不固定,但是必须是2MB的倍数,有可能比中型Region小,只会存一个对象而且不会被重分配。

  • 中型Region:容量固定为32MB,用于放置大于等于256KB小于4MB大小的对象。

  • 小型Region:容量固定为2MB,用于放置小于256KB的对象。

并发算法

ZGC中实现并发算法与Shenandoah中不一样,虽然也用到了读屏障但是没有使用转发指针,不过取而代之的是使用了染色指针技术

染色指针

介绍之前先提一下Linux中的64位的指针,该指针的高18位是不能用来寻址的,剩余的46位指针足够支持64TB内存。

染色指针是一种直接将少量额外信息存储在指针上的技术。而其就盯上了该指针的46位中的高4位提取出来存储四个标志信息,这也导致了ZGC能够管理的内存不能超过4TB。

染色指针有如下几个优势:

  1. 染色指针可以在某个Region的存活对象被移走后立即释放或者重用该Region。

  2. 染色指针可以大幅度减少垃圾收集过程中内存屏障的使用。

工作流程

ZGC收集器的工作流程主要分为四个阶段,并发标记并发预备重分配并发重分配并发重映射

并发标记:遍历对象图做可达性分析,会有短暂停顿,该标记标记在指针而不是对象上。

并发预备重分配:根据特定的查询条件统计得出本次收集过程中要清理的Region,并将这些Region组成重分配集,该重分配集只是决定了里面的存活对象会被重新复制到其他的Region中,而集合里面的Region则会被释放

并发重分配:该阶段要把重分配集中的存活对象复制到新的Region中并为重分配集中的每个Region维护一个转发表,用来记录旧对象到新对象的转发关系。

并发重映射:修正整个堆中指向重分配集中旧对象的所有引用。ZGC把并发重映射阶段要做的工作合并到下一次垃圾收集循环中的并发标记阶段去完成,因为并发标记阶段也需要遍历全部对象,这样可以省去一次遍历对象图的开销。