首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ZGC垃圾收集器原理分析

ZGC垃圾收集器原理分析

作者头像
歪歪梯
发布2020-06-19 16:17:24
1K0
发布2020-06-19 16:17:24
举报
文章被收录于专栏:歪歪梯Club歪歪梯Club

着色

zgc只支持64位系统,然后最大支持4T的堆内存,64位指针只需要使用42位就可以寻址4TB的空间,这意味着有多余的22位可以利用。zgc利用了4位,分别用来表示:是否已经finalize,重映射(remap),mark0,mark1。 mark0与mark1表示是否被标记,在gc周期性更换,这样可以不要重复去复原(就像以前survivor的复制回收算法,也就是这次用mark0表示,下次就用mark1,在用mark1标记时顺便把mark0复原,在用mark0标记时顺便把mark1复原)。

读屏障

zgc引入读屏障,也就是通过gc root对象读取其他堆对象时,触发读屏障,做一些事情,再读取。

分页

zgc将堆分为 2M(small), 32M(medium), n*2M(large)三种大小的页面(Page)来管理,根据对象的大小来判断在那种页面分配

gc过程

标记阶段

标记阶段将对象指针的remap位标记为未完成重定向并加入存活队列。 1.stop the world,标记所有gc root对象,将每个页上存活的gc root对象,保存在该页对应的存活表(bitmap来实现)。 2.恢复应用程序,进入并发递归标记所有对象阶段,这个阶段中,因为有读屏障的存在,脏的对象会再加入待标记队列,等待标记。 3.stop the world,并发递归标记结束,将脏队列遍历标记完

重定位阶段

1.并发的找出几个需要重定位的内存页 2.stop the world,将所有gc root对象重定位过去,重定位完成则指针的remap标记恢复为重定位完成 3.并发重定位 这个阶段为了提高效率,并且避免脏读取,会利用一个映射表,将旧地址映射到新地址。当出现脏读取时,会先判断是否当前指针已经被重定向,如果没有直接返回引用。否则代表重定向未完成,判断当前引用的地址是否在映射表里,如果没有代表还没加入映射表(在脏队列没有遍历到),直接修改remap标记为已完成(退出脏队列,避免被重定位)等待下一次的gc再来处理这个脏对象。如果在映射表里有是代表正在开启重定向,接着根据映射的地址判断是否已经完成重定位,如果是修改当前引用到新地址,并返回对象引用。否则执行relocate object,应用程序主动帮助将对象重定向到新地址并修改当前引用到新地址,返回对象引用。

并发重定位

下一次zgc标记

1.此时mark0和mark1交换,标记时复原上一轮使用到的标记位 2.清空重定向表

总结

zgc是充分利用多线程和大内存(zgc的分页会根据cpu核优先分靠近的内存),适合大堆和服务器多核的配置。因为大部分stop the world都是遍历gc root对象,所以暂停时间不长。对比g1的话,感觉是g1虽然是按照吞吐量来选择最优的region进行回收,但是其拷贝移动的过程还是要stop the world(因为g1只有写屏障没有读屏障),而这点zgc就有优势,其通过读屏障、remark标记和重定向表来并发拷贝非gcroot对象。并且zgc还根据新的linux系统有一些底层的优化。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 歪歪梯Club 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 着色
  • 读屏障
  • 分页
  • gc过程
    • 标记阶段
      • 重定位阶段
        • 下一次zgc标记
          • 总结
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档