对象分代年龄上限为15,是因为hotspot jvm对象头mark word中仅分配4 bit存储该字段,最大值为2⁴−1=15;再多一位会覆写锁状态或hashcode等关键信息,且98%对象活不过首次minor gc,15次已足够标识长期存活对象。

因为HotSpot JVM对象头里的Mark Word只分配了4个bit位专门存分代年龄,而4 bit能表示的无符号整数范围是0到15(二进制0000~1111),再多一位就会覆盖相邻字段。
对象头中Mark Word的位布局是硬性约束
在64位HotSpot虚拟机中,Mark Word占8字节(64 bit)。这64 bit被精细划分给不同用途:
- 约25 bit用于存储identity hashcode(未锁定时)
- 4 bit固定分配给GC年龄字段
- 2 bit用于锁状态标志(01轻量锁、10重量锁、11偏向锁等)
- 其余位用于偏向线程ID、epoch、是否偏向等
这4 bit是物理上“划死”的——不是预留、不是可扩展区域,而是与其他关键元数据共享同一块紧凑结构。写入第5位(即数值≥16)会直接覆写锁标志位或hashcode低位,导致对象状态错乱,JVM无法正确识别锁状态或计算哈希值。
不是设计选择,而是位宽封顶
这个限制和“身份证号码18位”类似,不是经验推荐值,而是存储容器本身容量已满:
- 0000 → 年龄0(刚进入Survivor)
- 1111 → 年龄15(4 bit最大值)
- 10000 → 需要5 bit,但第5位在Mark Word中已被锁标志占用
所以-XX:MaxTenuringThreshold设为16及以上时,JVM启动会报错或静默截断为15,本质是防止底层bit越界写入。
为什么没用更多bit?空间效率优先
JVM堆中每个对象都要携带这个Mark Word,哪怕只多用1 bit,乘以亿级对象就是GB级内存浪费:
- 若扩到5 bit,年龄上限升至31,但所有对象Mark Word需从8字节涨到9字节(需整体对齐)
- 实测表明98%对象活不过首次Minor GC,真正需要计龄的对象极少
- 用4 bit平衡了精度、空间与实用性,是典型的“够用就好”工程取舍
年龄达到15后不等于必须晋升
达到年龄15只是触发晋升的条件之一,最终是否进入老年代还取决于:
- 目标Survivor区是否有足够连续空间容纳该对象
- 是否开启动态年龄判断(如某次GC后,Survivor中累计50%以上对象年龄≥5,就提前晋升所有≥5的对象)
- 对象大小是否超过Survivor容量阈值
也就是说,15是年龄字段的存储上限,不是晋升的绝对指令。











