分配担保是HotSpot VM在Minor GC前预判老年代能否容纳晋升对象的安全机制:先检查老年代最大连续空闲空间是否≥新生代存活对象总量,若不满足则比对是否≥历史晋升平均大小且-XX:+HandlePromotionFailure启用,否则直接触发Full GC。

当老年代空间不足时,对象分配担保机制不会“主动触发”新动作,而是让一次本该在新生代发生的 Minor GC 失败,并被迫升级为 Full GC(或 G1 中的 Mixed GC / ZGC 中的暂停回收等对应行为),核心逻辑是“担保失败 → 回退处理”。
什么是分配担保(Allocation Guarantee)?
这是 HotSpot VM 在执行 Minor GC 前做的安全检查:JVM 预估本次 GC 后,所有存活对象(含本次 GC 晋升的对象)能否全部放入老年代。判断依据包括:
- 老年代最大可用连续空间是否 ≥ 历史晋升平均大小(基于之前 Minor GC 的晋升数据)
- 是否开启了 -XX:HandlePromotionFailure(JDK 7 及以前默认 true;JDK 8+ 默认 false,即直接失败)
- 老年代剩余空间是否 ≥ 当前新生代所有存活对象总大小(保守策略,部分收集器会用)
老年代空间不足时,担保如何“失败”?
不是单独触发一个机制,而是在 Minor GC 准备阶段就判定担保不成立,导致 GC 流程转向更重的操作:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 若启用 HandlePromotionFailure(已废弃,仅作理解):尝试进行一次 Full GC,清出老年代空间后再重试 Minor GC
- 若未启用(现代默认):直接放弃 Minor GC,抛出 Concurrent Mode Failure(CMS)或触发 Full GC(Serial/Parallel);G1 则可能提前启动 Mixed GC 或退化为 Full GC
- CMS 在并发预清理/可中断预清理阶段发现老年代碎片化严重、无法容纳预期晋升对象,也会宣告担保失败,进而启动 Concurrent Mode Failure 处理流程
常见表现与排查线索
这类问题通常伴随以下日志特征:
立即学习“Java免费学习笔记(深入)”;
- [GC (Allocation Failure) ...] → 表示 Minor GC 因空间不够触发,但后续若看到 [Full GC (Ergonomics)] 紧随其后,大概率是担保失败回退
- CMS 日志中出现 concurrent mode failure,说明并发回收来不及,老年代撑爆了
- G1 日志中频繁出现 to-space exhausted 或 evacuation failed,代表晋升目标(老年代区域)无足够空闲 Region
- jstat 显示老年代使用率长期 >90%,且每次 Minor GC 后老年代占用突增,说明晋升压力大、担保容易失败
如何降低担保失败概率?
关键不是“触发”它,而是预防它发生:
- 合理设置老年代初始大小(-Xms 与 -Xmx 接近),避免动态扩容带来的停顿和空间不足
- 调大老年代占比(如 Parallel GC 下用 -XX:NewRatio=2 降低新生代比例),给晋升留余量
- 减少大对象直接进入老年代(避免 -XX:PretenureSizeThreshold 设置过低,或避免频繁 new byte[4MB+])
- 对 CMS,启用 -XX:+UseCMSCompactAtFullCollection 和 -XX:CMSFullGCsBeforeCompaction 减少碎片(但 CMS 已弃用)
- G1 场景下,适当调高 -XX:G1HeapRegionSize 或 -XX:G1ReservePercent,预留更多可晋升空间


















