凌晨两点的告警:Old 区 12 分钟涨满 2 月 18 号凌晨 2 点 07 分,值班电话响了。监控看板上,我们的智能问答服务实例 qa-svc-7d9f 的老年代曲线是一条近乎垂直的直线:从 1.2 GB 到 5.8 GB 用了 12 分钟,然后 Full GC,STW 4.7 秒,接着又是一条
分代 ZGC 在我们的网关上跑了一年 去年十月,我们把 API 网关从 G1 换成了分代 ZGC,到这个月正好一年。这篇是完整的数据总结,包括参数、遇到的四个问题、以及我现在的看法。 先说结论:换成 ZGC 是我们这一年最值的一次技术决策,但它不是银弹,而且代价被大多数人低估了。 背景:为什么要换
我们一个网关服务,平时 P99 延迟 40ms 很稳,但每天凌晨批量任务后总有几次 200ms+ 的卡顿尖刺。G1 的 Mixed GC 停顿在堆大时是元凶。JDK 21 上 ZGC 已经成熟,我决定赌一把把它换上。 切换决策:先看停顿从哪来 先用 JFR 抓了一周 GC 数据。G1 在 16G 堆
现象:容器 4 核,GC 却开了 24 个线程 八月初一个 Pod 频繁被 K8s 驱逐,OOMKilled 日志看着是内存超了,但监控显示内存没到 limit。我进容器一查 CPU 使用率 400%——而这 Pod 只申请了 4 核。根因是 GC 线程数按宿主机 24 核算的,Parallel G
读源码的动机:1 毫秒停顿到底是什么换来的 五月的 JDK 21 EA build 里,分代 ZGC 已经能跑了。官方说停顿能控制在 1 毫秒内。我好奇的是——不分代的 ZGC 已经够强,为什么还要分代?翻了 GC 源码和 JEP 439,才把这件事想明白。 分代假设:大多数对象活不过第一轮 分代回
背景:为下半年的 JDK 21 LTS 提前做验证 四月我们开始评估下半年升级到 JDK 21 LTS 的可行性。GC 是这次升级最敏感的部分——ZGC 在 JDK 21 里终于要兑现「亚毫秒停顿」的承诺,Shenandoah 也迭代到第三代。我拉了 JDK 21 的早期 EA build(当时到
GC 选型的争论:Shenandoah 还是 ZGC 我们一个时延敏感的交易网关,之前用 G1,业务高峰 P99 偶尔冲到 400 ms,排查发现是 G1 的 Mixed GC 有 100~200 ms 的停顿。组里就"换哪个低延迟 GC"吵开了:有人挺 Shenandoah,有人挺 ZGC。我干脆
风控服务被 Full GC 拖出的长尾 2021 年 1 月底,风控服务的 P99 突然变差。这个服务是同步调用链路上的一环,上游给的超时是 800 ms,一旦它慢了,整个下单流程都会受影响。 当时的配置:JDK 8u272,8 G 堆,CMS + ParNew。 $ jstat -gcutil 1
实习生问我:这堆 GC 日志到底看什么 4 月底,团队来了个实习生。有次他看到我电脑上的 gc.log,问了一句:"这一行行的数字,你是怎么看出问题的?" 2021-04-28T09:14:22.118+0800: 341882.221: [GC (Allocation Failure) [PSY
十月的一个早晨:Full GC 每小时 40 次 十月二十六号一早,监控群里机器人在刷告警。报表服务的 Full GC 频率从平时的每小时 0~1 次,涨到了 40 次。 $ jstat -gcutil 1 2000 10 S0 S1 E O M CC