一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

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 控制,但类卸载需满足严苛条件,因此类元数据往往比对象存活得更久

热门栏目