直接看gc日志中老年代(ou)绝对增长量,结合剩余空间与full gc间隔估算爆仓时间;关键盯住每次full gc后ou残留值是否阶梯式上升,通过jstat采样、线性拟合斜率换算每日增长量,再计算剩余天数触发预警。

直接看 GC 日志里老年代(OU)的绝对增长量,再结合当前剩余空间和历史 Full GC 间隔,就能估算出爆仓时间点。关键不是看百分比,而是算“还剩多少字节、每天吃掉多少字节”。
盯住每次 Full GC 后的老年代残留量
真正决定爆仓风险的是:Full GC 执行完,老年代还剩多少没被回收的对象。如果这个值在逐次抬高,说明有对象长期驻留——比如从某次 FGC 后 OU = 1.8 GB → 下一次变成 2.1 GB → 再下一次变成 2.45 GB,这就是典型的阶梯式上涨。
- 用
jstat -gc <pid> 5000</pid>每 5 秒采样一次,提取OU(老年代已用字节)和OC(老年代容量)字段 - 只取 Full GC(不是 CMS 或 Young GC)之后的快照,过滤掉中间波动
- 记录连续 3~5 次 FGC 后的 OU 值,做线性拟合:
OU(t) = a × t + b,其中 t 是时间戳(秒),a 就是斜率(单位:字节/秒)
把斜率换算成可读的时间预警
假设你算出斜率 a = 1200 字节/秒:
- 每天增长 ≈ 1200 × 60 × 60 × 24 ≈ 103 MB/天
- 当前 OU = 3.2 GB,OC = 4.8 GB → 剩余空间 = 1.6 GB
- 理论剩余天数 = 1600 MB ÷ 103 MB/天 ≈ 15.5 天
这个数字就是“不干预情况下的软性临界”,不是精确倒计时,但足够触发预案。
必须排除干扰项,否则推算失真
- ✅ 排除元空间膨胀影响:加
jstat -gcmetacapacity <pid></pid>看 MU 是否同步上涨,若 MU 持续涨而 OU 也涨,可能是类加载泄漏间接拖累 GC 效率 - ✅ 排除直接内存挤压:用
jcmd <pid> VM.native_memory summary</pid>查 direct memory 使用量,超限会触发 JVM 主动收紧老年代回收策略 - ❌ 不要用
jstat -gcutil的 O% 做计算:40% 可能对应 1.92 GB(OC=4.8 GB),也可能对应 768 MB(OC=1.92 GB),脱离 OC 谈百分比毫无意义 - ❌ 不要拿 Young GC 后的 OU 瞬间跳变当趋势:YGC 只导致小幅 OU 上升,真正决定长期压力的是 Full GC 后的基线漂移
上线自动预警的最小可行逻辑
写个轻量脚本,每 10 分钟执行一次:
jstat -gc $PID | awk '/^[0-9]/ {print $3, $4}' | tail -n 5 > ou_oc.log
# 提取最近5次FGC后的OU/OC(需配合日志解析或人工标记FGC时刻)
# 算出 OU 增量均值,乘以 (OC - 当前 OU) / 增量均值 → 得小时级余量
只要推算出的余量
不复杂但容易忽略










