java对象晋升老年代由jvm自动决策,新对象默认分配在eden区,年龄为0;minor gc后存活对象移入survivor并增龄;满足年龄达标、动态年龄判断、survivor空间不足或大对象直入任一条件即晋升;晋升失败触发full gc。

Java对象从新生代晋升到老年代,不是靠手动控制,而是由JVM根据内存使用和GC策略自动决策的过程。核心目标是让长期存活的对象“安顿”在更稳定的老年代,减少在新生代频繁复制的开销。
新对象默认出生在Eden区
执行 new 操作时,绝大多数对象会优先分配在新生代的Eden区。此时对象年龄为0,尚未经历任何GC。只有两类例外会跳过Eden:
- 显式设置了
-XX:PretenureSizeThreshold,且对象大小超过该阈值(如设为4M,new byte[5_000_000]就直接进老年代); - 某些收集器(如Serial、ParNew)下,大对象因复制成本高,JVM主动绕过新生代。
Minor GC后存活对象移入Survivor并增龄
当Eden区满,触发Minor GC:
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 回收所有不可达对象;
- 存活对象(含Eden中活下来的 + 当前Survivor中仍存活的)被复制到另一个空的Survivor区(S0↔S1交替);
- 每成功经历一次Minor GC,对象年龄+1;
- 年龄始终记录在对象头中,不依赖引用关系。
满足任一条件即晋升老年代
对象不必等到年龄满15才走,以下任一情况发生时就会晋升:
-
年龄达标:达到
-XX:MaxTenuringThreshold设置值(默认15),下次GC时直接进入老年代; - 动态年龄判断:某次GC后,Survivor中“年龄为N”的所有对象总大小 > Survivor空间的一半,则所有年龄 ≥ N 的对象全部晋升;
- Survivor空间不足:Minor GC后,存活对象总量超出Survivor容量,多余部分(无论年龄)直接晋升;
- 大对象直入:创建时就超过预设阈值,跳过新生代,直接在老年代分配。
晋升失败会触发Full GC
如果老年代剩余空间不足以容纳即将晋升的对象,JVM会先尝试触发Full GC来腾出空间:
- 若Full GC后仍不够,抛出
java.lang.OutOfMemoryError: Java heap space; - 可通过
-XX:+PrintTenuringDistribution查看每次GC后的年龄分布,辅助调优阈值和Survivor大小。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










