前言 |
前面三篇文章讲了8种垃圾收集器分别是Serial、ParNew、Parallel Scavenge、Serial Old、Parallel Old、CMS、G1、Shenandoah,今天我们来说一下ZGC收集器,ZGC也是一款低延迟收集器,这款收集器也是非常的豪横,下面我们看一下它有什么可豪横的!
为何豪横 |
- 支持最大4T的堆大小
4T 4T 啊 铁子豪横吗 - 停顿时间不会超过10ms
而且停顿时间不会随着堆的增大而增大 - ZGC 没有分代的说法,所以没有跨代引用的问题
- 单凭上面3点就已经很哇塞了,ZGC还增加了染色指针
染色指针是一种直接将少量信息存储在指针上的技术
在64位的Linux操作系统下,高18位不能用来寻址,所以剩下46位,然后高四位用户存储4位标志信息,通过这些标志信息,可以看出对象的三色标记状态,是否进入重分配集,是否通过finalize()方法才能被访问到。所以说剩下42位的地址空间,也就是说ZGC最多可以管理2的42次方的空间,4TB
染色指针的优势
- 染色指针可以使得Region的存活对象被移走之后,这个Region立即就能够被释放和重用掉(这里用到了染色指针的自愈)
相比Shenandoah收集器来说,Shenandoah在回收Region区域的时候,如果极端情况所有对象都存活,那么需要一半的Region空间来复制,因为Shenandoah局部使用的标记-复制算法 - 染色指针不需要用卡表或者连接矩阵来记录对象的引用变化,它是直接将这些信息维护在指针中,这样就不需要用写屏障了,大幅度上提升了程序的运行效率
- 染色指针是一种可扩展的存储结构,例如在64位的Linux系统下,它的高18位是没有被使用的,所以说它是可扩展的
ZGC的运作过程 |
- 并发标记
和之前说到的G1、Shenandoah收集器一样 - 并发预备重分配
这个阶段是遍历所有的Region区域,标记所有存活的对象,和G1相比,ZGC没有来维护Region收益记录,所以要整堆遍历,这个过程是和用户线程并发的 - 并发重分配
将存活的对象复制到新的Region区,并维护一张转发表,记录旧对象和新对象的转向关系。如果期间有用户线程访问了旧对象,这时候ZGC会从引用上得知该对象是佛被重分配过,然后被内存屏障截获,并修改该对象的引用,ZGC将这种行为称为指针的 自愈 - 并发重映射
修改整个堆中的旧对象引用,因为有了指针的自愈功能,这个阶段显得不再迫切,所以这个阶段可下次遍历对象图一块执行
优点
除了上面所有的优点之外,还有以下特点
- 使用的标记-整理算法,没有内存碎片
- ZGC基本上是真正意义上的并发收集
缺点
ZGC无法应对很高的对象分配速率,因为并发的时候,新对象大都被标记为存活对象,而大多数对象都是朝生夕灭的,就会有大量的浮动垃圾。
总结 |
随着技术的日益发展,垃圾收集也越来越豪横,我们可根据自己的项目需求来选择收集器,来提高程序的性能。
这么一款豪横的收集器,你学废了吗?