JVM 堆区域与对象生命周期
探索新生代(Eden、Survivor)、老年代和元空间,以及对象如何在它们之间移动
JVM 堆区域与对象生命周期 是 CoddyKit 上的免费 Java Academy 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。
JVM 内存模型
JVM 将内存划分为多个区域。堆保存所有类实例和数组。堆外区域包括元空间(类元数据)、栈帧和本地内存。
新生代:Eden 区
新分配的对象会进入 Eden 区。当 Eden 区填满时,会执行一次次要垃圾回收。存活对象会被复制到 Survivor 区。
// Object allocation starts in Eden:
String s = new String("hello"); // allocated in Eden
List<Integer> list = new ArrayList<>(); // also EdenSurvivor 区:S0 和 S1
两个 Survivor 区(S0 和 S1)用于保存至少经历过一次垃圾回收仍然存活的对象。每次次要垃圾回收时,对象会在 S0 和 S1 之间交替移动。对象的年龄计数器会递增。
对象晋升阈值
当对象年龄超过晋升阈值(默认为 15)时,它会晋升到老年代。较大的对象可能跳过新生代,直接进入老年代。
// JVM flags:
// -XX:MaxTenuringThreshold=15 (default)
// -XX:PretenureSizeThreshold=1m (objects > 1MB go directly to Old Gen)老年代(长期存活区)
长期存活的对象位于老年代。主要垃圾回收(完整垃圾回收)会收集老年代,成本也更高。减少长期存活对象的数量,可以降低完整垃圾回收的频率。
元空间(Java 8 及更高版本)
元空间在 Java 8 中取代了 PermGen。它保存类元数据、方法字节码和字符串驻留数据。它使用本地内存并动态增长(上限由 -XX:MaxMetaspaceSize 设置)。
// Flag examples:
// -XX:MetaspaceSize=64m (initial Metaspace size)
// -XX:MaxMetaspaceSize=256m (cap to avoid native OOM)对象分配快速路径
JVM 使用线程本地分配缓冲区(TLAB),无需同步即可从 Eden 区分配对象。每个线程都有自己的一小块 Eden 区域。
对象生命周期:可达性
如果对象可以从垃圾回收根(栈变量、静态字段或 JNI 引用)访问到,那么该对象就是存活的。无法访问到的对象将成为可回收对象。
Object a = new Object(); // reachable via local variable
a = null; // now unreachable — eligible for GC软引用、弱引用和虚引用
SoftReference 会在 OOM 发生前被清除(用于缓存)。WeakReference 会在下一次垃圾回收时被清除。PhantomReference 用于对象回收后的清理。
Cache<String, Image> cache = new LinkedHashMap<>();
// Use SoftReference to let GC reclaim cache under memory pressure:
SoftReference<Image> ref = new SoftReference<>(loadHeavyImage());
Image img = ref.get(); // null if GC collected it对象终结(请避免)
finalize() 已被弃用且行为不可预测——垃圾回收器会在回收对象前调用它,但调用时机并无保证。请改用 Cleaner(Java 9 及更高版本)或 try-with-resources。
堆大小标志
使用 -Xms 设置初始堆大小,使用 -Xmx 设置最大堆大小。在生产环境中将两者设为相同值,以避免调整堆大小造成暂停。
// Recommended production flags:
// -Xms512m -Xmx512m (fix heap to 512 MB)
// -XX:NewRatio=2 (Old:Young = 2:1)快速检查
新分配的对象最初位于 JVM 堆的什么位置?
回顾
JVM 堆包含新生代(Eden 区和 Survivor 区)以及老年代。对象在经历多次次要垃圾回收后逐渐变老并晋升。元空间保存类元数据。可以通过 -Xms/-Xmx 和调优标志进行控制。
常见问题解答
「JVM 堆区域与对象生命周期」课时是免费的吗?
是的 — 「JVM 堆区域与对象生命周期」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。
「JVM 堆区域与对象生命周期」这节课中我会学到什么?
探索新生代(Eden、Survivor)、老年代和元空间,以及对象如何在它们之间移动 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Java Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。
「JVM 堆区域与对象生命周期」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Java Academy 课中编写并运行代码吗?
能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。