ZGC 回收流程

78 阅读2分钟

image.png

image.png

标记过程

  • 初始时,JVM 视图为 remapped,对象关系图如下。

image.png

  • 初始标记:STW,从GC Root出发,标记所有直接引用的对象。视图切换为 marked1。

    由于marked标记是marked0,所以会从marked0切换到marked1

image.png

  • 并发标记:遍历整个堆中存活的对象,当结束时,如果对象的视图为 marked1,那么说明对象是活跃的。同时还会记录下每页内存活的对象字节数大小,为后续迁移做准备。这个阶段新分配的对象,直接分配为 marked1。

    此时如果并不是第一次GC,还会完成上一轮 GC 的指针修复

image.png

  • 再标记:STW,处理并发标记未完成的任务,此处主要处理三色标记法漏标的问题,使用读屏障解决白色对象被黑色对象持有的问题。另外还会对非强根(软引用,虚引用等)进行并行标记

转移过程

  • 重置转移集:为后续迁移做准备,重置 page 的 Forwarding Tables,构建 Relocation Set(可回收页面集合)。这个阶段 ZGC 会扫码所有的的 page,与用户线程并发进行。

    • Forwarding Table:记录对象被迁移后的新旧引用的映射表。

    • Relocation Set:存放记录需要回收的存活 page 集合。

    第一次回收无需处理这一步

image.png

  • 初始转移:STW,找出所有 GC Roots 直接可达的对象,将其切换到 remapped。当 GC Roots 直接引用的对象需要迁移时,新对象被复制到新 page 后,修正 GC Roots 指向该对象的指针,进行'指针自愈'。

image.png

  • 并发转移:根据 Relocation Set 进行遍历,将存活对象复制到其他的 page,在 Forwarding Tabels 中记录对象新老引用地址的对应关系。当 page 中的对象迁移完毕后,page 会被回收。如果这个时候有用户线程访问了被迁移的对象,会根据 Forwading Tables 完成'指针自愈'

image.png

  • 重定位:此动作并不是本轮 GC 一定要进行的操作,当用户线程访问到对象时,会对其进行重定位也就是'指针修复',并且在下一轮 GC 的并发标记阶段,遍历的所有对象,也可以完成'指针自愈'

image.png

第二轮GC

image.png