贝利信息

JVM内存模型与垃圾回收_JVM内存区域划分与GC回收机制详解

日期:2026-01-18 00:00 / 作者:星降
堆内存是GC唯一真正干活的地方,程序计数器、虚拟机栈、本地方法栈生命周期与线程绑定,无需GC;方法区(Metaspace)回收条件苛刻、收益低;99%回收任务由Heap承担,对象分配于新生代Eden区,经Minor GC存活后进入Survivor,达年龄阈值或超大对象直接晋升老年代;Full GC代价高,应避免过早晋升;Metaspace虽取代PermGen,但配置不当仍会OOM;判断对象可回收仅依赖可达性分析,非引用计数;G1回收器按Region分区回收,Mixed GC兼顾新老代,但非全自动,需合理调参。

堆内存是GC唯一真正干活的地方

程序计数器、虚拟机栈、本地方法栈这三块区域,生命周期和线程完全绑定,入栈出栈时机确定,根本不需要GC介入。方法区(JDK 8+ 是 Metaspace)虽然理论上可回收废弃类和常量,但实际触发条件苛刻、收益极低,生产环境几乎不靠它减压。真正承担99%内存回收任务的,只有 Heap —— 所有 new 出来的对象、数组都落在这儿,也是 OutOfMemoryError: Java heap space 的唯一来源。

Metaspace 已取代 PermGen,但配置不当照样 OOM

JDK 8 彻底移除了永久代(PermGen),类元数据(类名、字段、方法签名、常量池等)改存本地内存,由 Metaspace 管理。这不是“不用管了”,而是换了一种溢出方式:java.lang.OutOfMemoryError: Metaspace

判断对象是否可回收,只看可达性分析,不是引用计数

JVM 不用引用计数法(Reference Counting),因为解决不了循环引用问题。所有主流实现都基于可达性分析(Reachability Analysis):以一组称为 GC Roots 的对象为起点,向下搜索引用链;任何对象到 GC Roots 不可达,即判定为可回收。

G1 回收器不是万能药,混合回收逻辑容易误判

G1(Garbage-First)是 JDK 9 默认、JDK 10+ 唯一支持的默认 GC,主打可预测停顿时间(-XX:MaxGCPauseMillis),但它不是“全自动优化器”。它的核心是把堆划分为多个大小相等的区域(Region),并按垃圾密度排序回收。

真正卡住人的从来不是概念,而是 MetaspaceSize 忘设、PretenureSizeThreshold 乱调、把 SoftReference 当强引用用、或者以为开了 G1 就不用看 GC 日志——这些细节不落地,模型再熟也没用。