g1中对象晋升指其从年轻代region迁移到老年代region的过程。对象年龄达阈值(默认15)、动态年龄判定超半、大对象直接进humongous region或空间担保失败时均会触发晋升。

G1中Region本身不“晋升”,真正发生晋升的是对象——而这些对象所在的Region,会随着对象的生命周期变化,其逻辑角色(如Eden、Survivor、Old)也随之改变。G1没有传统意义上的“Region晋升”机制,但对象从年轻代Region迁移到老年代Region的过程,就是大家常说的“晋升”。关键在于理解对象何时、以何种方式进入Old Region。
对象年龄达标自动进入Old Region
每个对象在新生代经历一次Young GC并存活后,年龄+1。默认最大年龄阈值为15(由-XX:MaxTenuringThreshold=15控制),当年龄达到该值,下次Young GC时就会被移入Old Region。这个过程发生在Young GC的复制阶段:Eden和Survivor中满足年龄条件的对象,直接被复制到空闲的Old Region(而非Survivor),该Region随即被标记为Old Region。
- 年龄不是固定计数器,而是按Young GC次数累加;未触发GC时年龄不会增长
- 若设-XX:MaxTenuringThreshold=1,对象熬过第一次Young GC就进老年代
- 年龄上限受4位二进制限制,理论最大值为15,无法设为16或更高
动态年龄判断提前触发迁移
当某次Young GC后,Survivor区中某个年龄档的对象总大小,超过Survivor总容量的一半,那么所有≥该年龄的对象都会被一并晋升到Old Region。这属于G1(及多数现代收集器)的自适应优化策略,避免Survivor区溢出导致担保失败。
- 例如:Survivor共8MB,所有4岁对象占4.2MB → 所有4岁及以上对象全部晋升
- 该判断在每次Young GC结束前执行,无需等待年龄达标
- 实际阈值可通过-XX:TargetSurvivorRatio微调(默认50%)
大对象直接分配至Humongous Region(视同老年代)
若对象大小超过一个Region容量的50%(如Region为2MB,则≥1MB即算大对象),G1会跳过Eden/Survivor,直接尝试在堆中寻找连续的Humongous Region(H-Region)存放。这类Region在逻辑上被归入老年代管理范畴:
- H-Region不参与Young GC,只在Mixed GC或Full GC中被回收
- 单个超大对象可能横跨多个连续H-Region(如数组占3.5MB,Region=2MB → 占用2个H-Region)
- 若找不到足够连续H-Region,G1可能触发Full GC来整理空间
空间担保失败时的被动迁移
Young GC前,JVM需确保老年代有足够空间容纳本次可能晋升的所有存活对象(即“空间分配担保”)。若检查失败(如老年代碎片化严重、可用空间不足),G1会启动一次并发标记周期,并尽快安排Mixed GC;若仍来不及,部分对象可能通过“分配担保失败降级”直接进入老年代——这种路径虽非常规,但在高负载或配置失当时真实存在。
- 典型诱因:老年代占用率已超-XX:InitiatingHeapOccupancyPercent(默认45%),但尚未完成并发标记
- 此时Young GC仍会进行,但部分本该留在Survivor的对象会被“挤”进Old Region
- 可通过监控G1EvacuationPause日志中的to-space-exhausted指标识别











