对象晋升阈值由-XX:MaxTenuringThreshold控制,决定新生代对象经历多少次Minor GC后晋升老年代;默认值因GC算法而异(Parallel为15、CMS为6、G1忽略),取值范围通常0–15;设为0时对象直接进入老年代。

对象晋升阈值由 JVM 参数 -XX:MaxTenuringThreshold 控制,它决定了对象在新生代(Young Generation)中最多经历多少次 Minor GC 后,仍存活就会被晋升到老年代(Old Generation)。
默认值与取值范围
该参数的默认值因 JVM 版本和垃圾收集器而异:
- 使用 Parallel GC 时,默认为 15(即最多 15 次 Minor GC)
- 使用 CMS GC 时,默认为 6
- G1 GC 中该参数基本被忽略(G1 使用动态年龄判断,而非固定阈值)
- 取值范围是 0–15(某些 JDK 版本支持最大 31,但实际有效上限仍受算法限制)
设置为 0 的含义
当 -XX:MaxTenuringThreshold=0 时,表示“不等待”,所有在 Eden 区经过一次 Minor GC 后幸存的对象,**直接进入老年代**(跳过 Survivor 区)。这适用于:
- 已知大部分对象生命周期极短,但少量对象天生“长寿”,提前晋升可减少 Survivor 区拷贝开销
- Survivor 空间频繁溢出(如日志中出现
Desired survivor size … is not enough) - 系统存在大量中等生命周期对象,反复在 Survivor 区复制反而增加延迟
如何判断是否需要调优
关键不是盲目设高或设低,而是观察 GC 日志中的年龄分布:
- 用
-XX:+PrintGCDetails -XX:+PrintTenuringDistribution查看每次 Minor GC 后各年龄对象大小 - 如果日志中显示“age 1: …”占绝大多数,且 age ≥ 2 的对象极少 → 可考虑降低阈值(如设为 1 或 2)
- 如果 age 分布较均匀,且老年代晋升量突增发生在 age 4–5 → 当前阈值可能偏高,可尝试设为 5
- 若 Survivor 区长期利用率低于 10%,说明对象晋升过早;若频繁触发
to-space overflow,说明晋升太晚或 Survivor 太小
配合 SurvivorRatio 一起调整
MaxTenuringThreshold 的效果高度依赖 Survivor 空间大小:
- Survivor 太小(如
-XX:SurvivorRatio=8,即 S 占 Young 的 1/10),即使阈值设为 15,对象也可能因空间不足被迫提前晋升 - 建议先通过日志确认 Survivor 实际使用率,再决定是调大
SurvivorRatio(减小比值数字,如设为 4),还是调低MaxTenuringThreshold - 典型组合:高吞吐场景倾向
-XX:SurvivorRatio=6 -XX:MaxTenuringThreshold=6;低延迟场景可能用-XX:SurvivorRatio=4 -XX:MaxTenuringThreshold=3

















