动态年龄判定机制默认启用,需开启-xx:+useadaptivesizepolicy才生效,依据-xx:targetsurvivorratio(默认50%)累加各年龄对象大小,首次超限时的年龄即为晋升阈值,且不超过-xx:maxtenuringthreshold;可通过gc日志中“new threshold”确认实际值。

JVM 动态年龄判定不是靠“单独配置”开启的,而是一套依赖多个参数协同工作的自适应机制。它默认启用,但需要满足条件才会实际生效。
必须启用自适应策略
动态年龄判定的前提是开启 -XX:+UseAdaptiveSizePolicy(默认已开启)。如果被显式关闭(如加了 -XX:-UseAdaptiveSizePolicy),整个机制就失效,JVM 会退回到严格按 -XX:MaxTenuringThreshold 的固定值晋升。
核心控制参数
以下三个参数共同决定动态阈值如何计算:
- -XX:TargetSurvivorRatio:默认 50,表示“当 Survivor 中某一年龄段及更小年龄对象累计占用 ≥ Survivor 总容量 × 50% 时,就触发该年龄及以上的对象晋升”。可设为 60、70 等,调高会延迟晋升;设太低(如 20)易导致 age1 就晋升。
- -XX:MaxTenuringThreshold:动态计算出的晋升年龄不会超过此值。Parallel 和 CMS 默认为 6,G1 默认为 15。它只是上限,不参与日常计算。
- -XX:SurvivorRatio:影响 Survivor 区大小。例如设为 6(Eden:S0:S1 = 6:1:1),每个 Survivor 占年轻代 1/8;若设为 2(即各占 1/4),Survivor 过小,极易因 age1 对象就超 TargetSurvivorRatio 而频繁提前晋升。
如何确认是否生效
添加 GC 日志参数:-XX:+PrintGCDetails -XX:+PrintGCTimeStamps,观察 Minor GC 日志中类似:
Desired survivor size 524288 bytes, new threshold 2 (max 6)其中 new threshold 就是本次动态算出的晋升起点年龄。若它在多次 GC 中变化(如 3→2→4),说明机制正在工作;若长期稳定等于 max 值,说明当前 Survivor 使用率低,未触发动态调整。
调优建议
- 不要盲目调大 MaxTenuringThreshold,对象生命周期短时,强行延迟晋升反而增加 Survivor 复制开销。
- 若发现 new threshold 频繁为 1 或 2,优先检查 SurvivorRatio 是否过小,或是否存在一批生命周期高度一致的短期对象(如批量 DTO)。
- 监控 GC 日志中的 Survivor 占用率(如 from space 1024K, 42% used),确保 GC 后有足够剩余空间容纳新存活对象。











