最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Java 对象在堆中各个分区的生命周期
时间:2026-07-08 10:08:45 编辑:袖梨 来源:一聚教程网
Java对象生命周期由JVM分代管理决定:新对象默认分配在Eden区,存活对象经Survivor区多次复制(年龄达15)晋升老年代,最终在老年代GC时回收,并可能触发元空间类卸载。
Java 对象在堆中不同分区的生命周期,本质是 JVM 分代管理策略与对象存活时间匹配的结果——不是对象“选择”去哪,而是它“活多久”决定了它在哪。
对象出生:绝大多数落在 Eden 区
新对象默认在新生代的 Eden 区分配。JVM 执行 new 时,先检查 Eden 是否有足够连续空间;有则直接分配,无则触发 Minor GC。
- 99% 的新对象在此诞生,且多数在下一次 Minor GC 前就已不可达
- 大对象(如超长数组)可能被 JVM 判定为“不适合复制”,直接分配到老年代,避免 Survivor 区频繁搬运
- TLAB(线程本地分配缓冲区)是 Eden 内的私有小块,不改变归属——仍在堆内,只是分配更快、无锁
对象暂存:在 Survivor 区间辗转存活
Minor GC 后仍存活的对象,会被复制到一个 Survivor 区(S0 或 S1),年龄 +1;下次 GC 时再复制到另一个 Survivor 区,持续交换。
- 每次复制成功,对象年龄加 1;默认阈值为 15,达到即晋升老年代
- Survivor 区大小通常各占新生代 10%,太小易导致“过早晋升”,太大则浪费空间
- 若某次 GC 后 Survivor 区放不下所有存活对象,多余部分直接进入老年代(担保机制)
对象长驻:晋升老年代后等待终结
老年代存放长期存活对象,GC 频率低但耗时长(Major GC / Full GC)。对象进入后,生命周期取决于是否还有 GC Roots 可达。
立即学习“Java免费学习笔记(深入)”;
- 静态变量、活跃线程栈帧、常量池引用等仍指向该对象 → 继续存活
- 所有引用链断开 → 标记为垃圾,等待下一次老年代 GC 回收
- 若对象所属类已无实例且其 ClassLoader 被回收,方法区(元空间)中的类元数据也会被卸载
对象退出:回收不止清堆,还联动清理元信息
对象消亡不是单点事件,而是堆与方法区协同完成的过程:
- 堆中空间由 GC 算法(如 G1 的 Region 回收、ZGC 的染色指针)真正释放
- 若该对象是某个类的最后一个实例,且该类加载器已不可达,则其类名、字段、方法等元数据从元空间移除
- 元空间位于本地内存,不受堆 GC 控制,但类卸载需满足严苛条件,因此类元数据往往比对象存活得更久
相关文章
- 《Disney Lorcana: Wilds Unknown》预购开启 首批《Toy Story》及皮克斯卡牌购买指南 07-29
- 车来了赶车闹钟如何设置 07-29
- 崩坏星穹铁道余晖残卷巨剑守护打法攻略 07-29
- 崩坏星穹铁道砂金角色部分背景介绍 07-29
- 崩坏3雷电芽衣什么时候上线 07-29
- 玩具熊的五夜后宫4代噩梦气球男孩Nightmare Balloon Boy介绍 07-29