揭开ZGC(垃圾收集器的神秘面纱)

一、什么是ZGC

ZGC 全称 The Z Garbage Collector 是JDK 11中推出的一款追求极致低延迟的垃圾收集器,注意至少是JDK11把版本才能支持,目前流行的主流版本不支持。它曾经设计目标包括:
1、停顿时间不超过10ms(JDK16已经达到不超过1ms);
2、停顿时间不会随着堆的大小,或者活跃对象的大小而增加;
3、支持8MB~4TB级别的堆,JDK15后已经可以支持16TB。
听起来很牛逼,接下来看看他是这么实现的:

二、ZGC垃圾回收过程

首先:ZGC中没有分代的概念(新生代、老年代)和G1一样,ZGC将内存划分成小的分区,在ZGC中称为页面(page)ZGC有三种页面
1、小页面、是2MB的页面空间、当对象大小小于等于256KB时,对象分配在小页面。
2、中页面、中页面指32MB的页面空间、当对象大小在256KB和4M之间,对象分配在中页面。
3、大页面、大页面指受操作系统控制的大页,当对象大于4M,对象分配在大页面。
整体流程:


1665495931(1).png

1、初始阶段:这个阶段需要暂停(STW),初始标记只需要扫描所有GC Roots,其处理时间和GC Roots的数量成正比,停顿时间不会随着 堆的大小或者活跃对象的大小而增加。
2、并发标记:这个阶段不需要暂停(没有STW),扫描剩余的所有对象,这个处理时间比较长,所以走并发,业务线程与GC线程同时运行。 但是这个阶段会产生漏标问题。
3、再标记:这个阶段需要暂停(没有STW),主要处理漏标对象,通过SATB算法解决(G1中的解决漏标的方案)。
4:并发转移准备 :分析最有回收价值GC分页(无STW)
5、初始转移(转移初始标记的存活对象同时做对象重定位(有STW)
6、并发转移(对转移并发标记的存活对象做转移<无STW>)

这个过程有几个点需要注意
1、ZGC对对象的标记不再是用对象头记录的方式,而是采用了颜色指针标记:颜色指针标记是指:ZGC只支持64位系统(使用64位指针),ZGC中低42位表示使用中的堆空间,然后、ZGC借几位高位来做GC相关的事情(快速实现垃圾回收中的并发标记、转移和重定位等)如图:


image.png

2、如何做到并发转移?
在并发转移的过程中需要记录转发表,由于ZGC采用颜射指针标记,当把存活对象复制到新的区域的时候,指向原本区域的指针如何能够知道该对象已经复制到了新的对象,从而指向新区域呢,这就需要在转移过程中记录一张转发表:记录从旧对象 到新对象的转向关系
3、读屏障
涉及对象:并发转移但还没做对象重定位的对象
触发时机:在两次GC之间业务线程访问这样的对象
触发操作:对象重定位+删除转发表记录(两个一起做原子操作)
读屏障是JVM向应用代码插入一小段代码的技术。当应用线程从堆中读取对象引用时,就会执行这段代码。
ZGC中GC触发机制:
1、预热规则:JVM启动预热,如果从来没有发生过GC,则在堆内存使用超过10%、20%、30%时,分别触发一次GC,以收集GC数据.
2、基于分配速率的自适应算法:最主要的GC触发方式(默认方式),其算法原理可简单描述为”ZGC根据近期的对象分配速率以 及GC时间,计算出当内存占用达到什么阈值时触发下一次GC”。通过ZAllocationSpikeTolerance参数控制阈值大小,该参数 默认2,数值越大,越早的触发GC。
3、基于固定时间间隔:通过ZCollectionInterval控制,适合应对突增流量场景。流量平稳变化时,自适应算法可能在堆使用率达 到95%以上才触发GC。流量突增时,自适应算法触发的时机可能会过晚,导致部分线程阻塞。我们通过调整此参数解决流量突 增场景的问题,比如定时活动、秒杀等场景。
4、主动触发规则:类似于固定间隔规则,但时间间隔不固定,是ZGC自行算出来的时机,我们的服务因为已经加了基于固定时间 间隔的触发机制,所以通过-ZProactive参数将该功能关闭,以免GC频繁,影响服务可用性。
5、 阻塞内存分配请求触发:当垃圾来不及回收,垃圾将堆占满时,会导致部分线程阻塞。我们应当避免出现这种触发方式。日志 中关键字是“Allocation Stall”。
6、外部触发:代码中显式调用System.gc()触发。 日志中关键字是“System.gc()”。
7、元数据分配触发:元数据区不足时导致,一般不需要关注。 日志中关键字是“Metadata GC Threshold”。
ZGC参数设置:
1、堆大小:Xmx。当分配速率过高,超过回收速率,造成堆内存不够时,会触发 Allocation Stall,这 类 Stall 会减缓当前的用户线程。因此,当我们在 GC 日志中看到 Allocation Stall,通常可以认为堆空间 偏小或者 concurrent gc threads 数偏小。

2、GC 触发时机:ZAllocationSpikeTolerance, ZCollectionInterval。ZAllocationSpikeTolerance 用 来估算当前的堆内存分配速率,在当前剩余的堆内存下,ZAllocationSpikeTolerance 越大,估算的达到 OOM 的时间越快,ZGC 就会更早地进行触发 GC。ZCollectionInterval 用来指定 GC 发生的间隔,以秒 为单位触发 GC。

3、GC 线程:ParallelGCThreads, ConcGCThreads。ParallelGCThreads 是设置 STW 任务的 GC 线 程数目,默认为 CPU 个数的 60%;ConcGCThreads 是并发阶段 GC 线程的数目,默认为 CPU 个数的 12.5%。增加 GC 线程数目,可以加快 GC 完成任务,减少各个阶段的时间,但也会增加 CPU 的抢占开 销,可根据生产情况调整

ZGC 需要调整的参数十分简单,通常设置 Xmx 即可满足业务的需求,大大减轻 Java 开发者的负担

三、ZGC的优势

1、一旦某个Region的存活对象被移走之后,这个Region立即就能够被释放和重用掉,而不必等待整个堆中所有指向该Region的引用都被修正后才能清理,这使得理论上只要还有一个空闲Region,ZGC就能完成收集。
2、颜色指针可以大幅减少在垃圾收集过程中内存屏障的使用数量,ZGC只使用了读屏障。
3、颜色指针具备强大的扩展性,它可以作为一种可扩展的存储结构用来记录更多与对象标记、重定位过程相关的数据,以便日后进一步提高性能。

四、缺点:

它能承受的对象分配速率不会太高,ZGC准备要对一个很大的堆做一次完整的并发收集。在这段时间里面,由于应用的对象分配速率很高,将创造大量的新对象,这些新对象很难进入当次收集的标记范围,通常就只能全部当作存活对象来看待——尽管其中绝大部分对象都是朝生夕灭的,这就产生了大量的浮动垃圾。如果这种高速分配持续维持的话,每一次完整的并发收集周期都会很长,回收到的内存空间持续小于期间并发产生的浮动垃圾所占的空间,堆中剩余可腾挪的空间就越来越小了。目前唯一的办法就是尽可能地增加堆容量大小,获得更多喘息的时间。

五、如何选择垃圾收集器:

1、优先调整堆的大小让服务器自己来选择
2、如果内存小于100M,使用串行收集器
3、如果是单核,并且没有停顿时间的要求,串行或JVM自己选择
4、如果允许停顿时间超过1秒,选择并行或者JVM自己选
5、如果响应时间最重要,并且不能超过1秒,使用并发收集器
6、4G以下可以用parallel,4-8G可以用ParNew+CMS,8G以上可以用G1,几百G以上用ZGC
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342

推荐阅读更多精彩内容