JVM 堆内存分代模型

JVM 把堆内存分成不同「世代」,对不同生命周期的对象使用不同的垃圾回收策略,提升 GC 效率。

分代结构

分代存储对象回收策略特点
新生代(Young)刚创建的「短命对象」频繁回收(YGC/Minor GC)回收快、停顿短(毫秒级)
老年代(Old)存活久的「长命对象」少回收(Mixed GC/FGC)回收慢、停顿长(秒级)

元空间(Metaspace,JDK8+)是非堆内存,存储类元数据。

新生代(Young)

新生代是新对象分配的区域,细分为 3 个区,包括Eden/S0和S1,具体如下:

Eden 区(伊甸园)

  • 所有新对象优先分配到这里
  • 占新生代约 80%
  • YGC 的主要回收区域

Survivor 区(幸存区,S0 / S1)

  • 两个等大区域,同一时刻只有一个在使用
  • 作用:Eden 满触发 YGC 时,Eden 中存活对象移到 Survivor
  • 对象每经历一次 YGC 存活,「年龄+1」,达到阈值(默认 15)后晋升到老年代
  • Survivor 0(S0 / From Survivor)
  • Survivor 1(S1 / To Survivor)

S0 和 S1 交替工作:一个存存活对象(From),另一个空着等垃圾回收时接收对象(To),同一时刻只有一个在使用

YGC 完整流程

  1. Eden 满 → 触发 YGC
  2. 回收 Eden 死对象,存活对象移到空的 Survivor 区
  3. Survivor 满 / 对象年龄到阈值 → 移到老年代
  4. 清空 Eden,两个 Survivor 角色互换

老年代(Old)

  • 来源:Survivor 晋升来的对象 + 大对象(直接分配)
  • G1GC 下主要靠并发标记 + 混合回收清理
    • G1GC(Garbage-First GC)的设计目标是尽量减少 STW(Stop-The-World)时间。它把堆划分为多个大小相等的 Region (区域),老年代不再是一个连续区域。
    • 并发标记(Concurrent Marking) — 在应用运行时,G1 后台线程标记出老年代中仍然存活的对象。这个过程是并发执行的,不暂停应用。
    • 混合回收(Mixed GC) — 标记完成后,G1 不会只回收新生代,而是一次性回收新生代 + 部分老年代 Region(优先回收垃圾最多的 Region,即 “Garbage-First” 的由来)。
  • 老年代满 → 触发 Full GC(整堆回收,STW,性能杀手)
    • Parallel GC / CMS 等非 G1GC 的场景,或者是 G1GC 也兜不住的情况。
    • Full GC:
      • 对整个堆(新生代 + 老年代 + 元空间)进行全量回收
      • 全程 STW(Stop-The-World) — 所有应用线程暂停
      • 时间很长,通常几百毫秒到几秒甚至更久
    • 性能杀手:在延迟敏感的应用中,几秒钟的停顿可能导致连接超时、请求失败、服务雪崩。尤其是 Full GC 频率高时(比如一小时一次),系统会周期性”卡死”

典型的Full GC 触发条件

GC 策略触发 Full GC 的常见原因
Parallel GC老年代空间碎片化/不足
CMS并发模式失败(Concurrent Mode Failure)
G1GC并发标记赶不上对象分配速度 → 晋升失败(Promotion Failure)

分代设计目的

  • 新生代(占堆 1/3):频繁扫描,空间小、回收快(YGC 单次 20-50ms)
  • 老年代(占堆 2/3):很少扫描,快满时才回收,避免频繁全堆扫描

相关笔记