JVM 分代空间工作流程:对象从创建到回收的完整生命周期
这是 JVM 最核心、面试必问、线上调优必须吃透的全流程闭环 ,我用最清晰、一步不丢的方式给你整理出来,看完就能彻底理解。
一、先记住:JVM 堆的标准分代结构
plaintext
堆 Heap
├─ 年轻代 Young Gen(1/3)
│ ├─ Eden 伊甸区 (80%)
│ ├─ S0 幸存者区0 (10%)
│ └─ S1 幸存者区1 (10%)
│
└─ 老年代 Old Gen(2/3)
固定规则:
- S0 和 S1 永远只有一个有数据,另一个必须空
- 新对象 → Eden
- 活很久的对象 → 老年代
二、完整版流程:对象从出生到死亡(一步一步)
第 1 步:对象诞生 ------ 分配在 Eden 区
- 所有新对象 优先在 Eden 区分配内存
- Eden 区很小,很快就会被填满
- 此时对象 = 新生对象
java
运行
User user = new User(); // 直接进 Eden
第 2 步:Eden 满 → 触发 Minor GC(年轻代 GC)
当 Eden 区没有空间分配新对象时:
- 触发 Minor GC
- STW(Stop The World) 暂停所有业务线程
- 扫描 Eden + 正在使用的 Survivor 区
- 存活对象 标记,垃圾对象 直接清除
特点
- Minor GC 极快
- 发生频率非常高
- 只回收年轻代
第 3 步:存活对象复制 → 空的 Survivor 区
Minor GC 后:
- Eden 清空
- 存活对象 → 复制 到空的 Survivor 区(S0 或 S1)
- 对象年龄 +1
关键规则
- S0 和 S1 必须交替使用
- 一次 GC 后:一个空、一个存数据
- 这种机制叫 复制算法,无内存碎片
第 4 步:对象在 Survivor 区来回 "轮换"
每触发一次 Minor GC:
- 存活对象 从当前 S 区 → 复制到另一个空 S 区
- 年龄 +1
- 原来的 S 区 清空
对象就在 S0 ↔ S1 之间来回移动。
第 5 步:年龄达标 → 晋升老年代
当对象年龄达到 阈值(默认 15)
- 直接进入 老年代
- 不再参与 Survivor 轮换
晋升老年代的 4 种条件(必背)
- 年龄达到 15 (默认,可通过
-XX:MaxTenuringThreshold设置) - 大对象(大数组、长字符串)直接进入老年代
- Survivor 区 相同年龄的对象总大小 > Survivor 空间一半
- Minor GC 后存活对象 太多,放不进 Survivor
第 6 步:老年代空间不足 → Major GC / Full GC
老年代存放长期存活对象,一旦满了:
- 触发 Major GC / Full GC
- STW 时间变长(比 Minor GC 慢 10 倍以上)
- 回收整个堆:年轻代 + 老年代 + 元空间
重点
Full GC 是线上卡顿、CPU 高、服务雪崩的头号元凶!
第 7 步:老年代存活对象最终被回收
- 老年代的对象如果长期没有引用
- 在 Full GC 时被回收
- 对象生命周期正式结束
三、一张图看懂完整生命周期(最强总结)
plaintext
新对象
↓
Eden 区分配
↓
Eden 满 → Minor GC
↓
存活对象 → S0 / S1(年龄+1)
↓
S0 ↔ S1 轮换(每次GC年龄+1)
↓
年龄达标 / 大对象 / Survivor 空间不足
↓
晋升老年代
↓
老年代满 → Full GC
↓
对象被回收 / 永久存活
四、核心关键词(面试直接背)
- Eden:新对象出生地
- Minor GC:回收年轻代,速度快
- Survivor:对象轮换区,无碎片
- 年龄:决定对象何时进入老年代
- 老年代:存长期存活对象
- Full GC:慢、卡顿、线上大忌
- 复制算法:年轻代使用,无碎片
- 标记整理 / 标记清除:老年代使用
五、高频面试题(标准答案)
1. 对象从创建到回收经历了哪些区域?
Eden → S0 → S1 → 老年代 → 被 GC 回收
2. 对象什么时候进入老年代?
年龄 15、大对象、Survivor 空间不足、年龄动态判断。
3. 为什么需要 Survivor 区?
避免对象过早进入老年代,减少 Full GC。
4. Minor GC 和 Full GC 区别?
- Minor GC:年轻代、快、频繁
- Full GC:全堆、慢、卡顿、少发生
5. 为什么分代?
不同对象生命周期不同,分代可以让 GC 效率最高。
总结
JVM 分代工作流程 = 对象出生 → 年轻代轮换 → 晋升老年代 → 最终回收 整个流程围绕 Eden → Survivor → Old 展开,是理解 GC、OOM、JVM 调优的基础。