Java堆是JVM内存中最大且线程共享的区域,专用于存放new创建的对象和数组;它划分为新生代(Eden、S0、S1)和老年代,基于分代思想配合Minor GC与Major/Full GC自动管理内存。

堆内存是Java对象的唯一落脚地,所有通过new创建的对象、数组都分配在堆中,由所有线程共享。它的分配与回收不是手动控制的,而是由JVM自动管理——核心机制就是“分代设计 + 垃圾回收(GC)”。
堆内存按生命周期分区域管理
堆逻辑上划分为新生代和老年代,这种划分基于“绝大多数对象朝生夕死”的统计规律:
- 新生代:默认占堆总空间约1/3,专放新创建对象。它又细分为Eden区(约80%)、Survivor0(S0)和Survivor1(S1)两个等大小区域(各约10%)。
- 老年代:默认占堆约2/3,存放长期存活对象,比如Spring容器中的单例Bean、缓存对象等。
- 元空间(Metaspace):不属于堆,但常被关联提及;它存储类的元数据(类信息、常量池、静态变量等),位于本地内存,取代了Java 8之前的永久代。
对象如何分配与晋升
对象不是一出生就固定在某处,而是在GC过程中动态流转:
- 新对象优先分配到Eden区;
- Eden满时触发Minor GC,存活对象被复制到一个Survivor区(如S0),年龄设为1;
- 下一次Minor GC时,S0中仍存活的对象年龄+1,并复制到S1;S0和S1角色互换;
- 对象年龄达到阈值(默认15)或Survivor区内同龄对象总大小超一半,就会直接晋升到老年代;
- 大对象(如大数组)可能直接分配到老年代,避免在新生代反复复制。
垃圾回收如何触发与执行
GC不是定时运行,而是由内存压力驱动:
- Minor GC:Eden区空间不足时触发,只清理新生代,采用复制算法,速度快、停顿短;
- Major GC / Full GC:老年代空间不足时触发,会回收整个堆(含新生代、老年代),还可能清理元空间;采用标记-清除或标记-整理算法,耗时长、STW(Stop-The-World)明显;
- 显式调用
System.gc()仅是建议,JVM可忽略;真正决定GC的是内存使用状态,而非代码调用。
关键细节影响实际表现
几个参数和行为容易被忽视,却直接影响GC频率和性能:
- 新生代与老年代比例可通过
-XX:NewRatio调整; - Survivor区比例受
-XX:+UseAdaptiveSizePolicy影响,默认开启,JVM会动态微调Eden/Survivor大小; - 对象晋升阈值由
-XX:MaxTenuringThreshold控制,但JVM也可能根据Survivor空间使用情况提前晋升; - 内存担保机制会在Minor GC前检查老年代是否足够容纳待晋升对象,否则可能提前触发Full GC。

















