随着互联网技术的飞速发展,面向个人用户C端系统对性能和用户体验变的尤为重要,高并发、高性能、高可用系统的建设已经成为众多企业和开发者追求的目标。在构建这类系统时,内存管理和垃圾回收机制显得尤为重要。本文将浅谈ZGC部分特性及在三高系统的实践应用。
ZGC是什么?
ZGC(Z Garbage Collector,Z垃圾收集器)是一款在Java 11中引入的垃圾回收器,它具有可扩展性、低延迟和大堆处理能力的特点。ZGC能够在不停止应用程序线程超过10毫秒的情况下并发执行所有回收操作,从而达到降低延迟的设计目的。
ZGC有哪些主要特性
相较于其他垃圾收集器,ZGC具有以下优势:
- 低延迟:将停顿时间控制在10ms以内,这对于高性能的C端系统来说非常关键。
- 高吞吐量:在降低延迟的同时,还能保持较高的吞吐量。
- 大内存支持:支持TB级别的堆内存,这使得它非常适合处理大数据和内存密集型应用。
- 易于使用:配置和调优相对简单,开发者可以更加专注于业务逻辑的实现。
ZGC能帮我们解决什么问题?
以美团外卖场景为例,首页的加载速度直接影响用户体验及订单量。提供品类导航的供给服务在午高峰及各种秒杀活动时YGC耗时达到几百毫秒,经常无法满足TP999的约定。针对YGC耗时过长的问题,我们进行了系统优化以及JVM参数调优,收效甚微,为了能支撑更高的QPS,只能进行横向扩容,直接增加了资源成本。
而ZGC的设计目标之一是把垃圾回收的停顿时间控制在10ms以内,使用ZGC可以大大减少垃圾回收期间的暂停时间,从而提高应用程序的响应能力和性能,更好地应对高并发、高性能和高可用的业务场景。
ZGC怎么解决这些问题?
分析其他回收算法不难发现,对象转移是整个gc周期耗时最长的环节,而且耗时与堆的大小成正比。ZGC采用了改进版的“标记-复制”算法,实现了在标记、转移和重定位阶段的应用线程、回收线程的并发执行,这就是ZGC停顿时间短的小的主要原因。与G1相比,ZGC在整个垃圾回收周期只有三个阶段需要STW,而且停顿时间不会随着堆的大小或者活跃对象的增加而延长,只与GC Roots的数量成正比。
ZGC通过“读屏障”、“着色指针”技术的应用,解决了转移过程中准确访问对象的问题,实现了并发转移。当应用线程访问对象时会触发执行“读屏障”,如果对象已经被转移,则会根据地址映射访问对象的新地址,这就保证了在对象转移后应用线程不会发生错误,从而实现应用线程、回收线程的并发执行。
读屏障实例:
Object o = obj.FieldA // 从堆中读取对象引用,需要加入读屏障
<load barrier needed here>
Object p = o // 无需加入读屏障,因为不是从堆中读取引用
o.dosomething() // 无需加入读屏障,因为不是从堆中读取引用
int i = obj.FieldB // 无需加入读屏障,因为不是对象引用
ZGC的应用带来的收益有哪些
虽然ZGC有诸多优势,但也并不是所有场景都适合应用。ZGC只在特定情况下具有绝对的优势, 如大堆和极低的停顿需求。
美团到家事业群的商品中心和业务集成团队承接了多个业务线的C端流量,通过ZGC的实践应用,系统性能得到较大提升,应用集群规模减少1/4-1/3,大大降低系统运行资源成本,在降本增效大背景下,通过从CMS到ZGC的迁移获得了客观的收益。
需要注意的是,实际性能提升取决于具体应用场景和配置。在某些情况下,CMS或G1可能仍然能够满足应用程序的需求。但总体来说,ZGC在大内存应用和对低延迟有要求的场景下具有明显的性能优势。