Java垃圾回收机制的核心目标是防止内存泄漏、消除手动释放错误、维持系统可预测性;通过可达性分析判断对象生死,依分代假说采用复制、标记-清除、标记-整理等算法协同工作。

Java 垃圾回收机制的核心目标不是“自动清理”,而是在保障程序可用内存持续充足的前提下,让开发者不必操心对象何时释放。它不追求零停顿或绝对高效,而是在内存安全、吞吐量、响应延迟之间做务实权衡。
核心目标:三个不可妥协的底线
• 防止内存泄漏:确保长期运行中,无用对象不会累积占用堆空间,避免 java.lang.OutOfMemoryError: Java heap space
• 消除手动释放错误:不用像 C/C++ 那样调用 free() 或担心重复释放、释放后使用(use-after-free)
• 维持系统可预测性:通过分代、并发等设计,把 GC 对业务线程的干扰(Stop-The-World)控制在合理范围内,尤其对 Web 服务、实时交易等场景至关重要
算法本质:怎么知道一个对象该被回收?
判断依据只有一种——可达性分析(Reachability Analysis),而非引用计数。
JVM 从一组被称为 GC Roots 的对象出发(如栈帧里的局部变量、静态字段、JNI 引用等),顺着所有引用链向下搜索。凡无法触达的对象,即被判定为“死亡”,进入回收候选。
主流回收算法:按对象存活特征匹配策略
• 复制算法(Copying):专用于新生代(Eden + Survivor)。假设“绝大多数对象朝生夕灭”,只需复制少量存活对象到另一块区域,清空原区即可。高效、无碎片,但代价是牺牲一半可用空间(如 Eden:S0:S1 = 8:1:1)
• 标记-清除(Mark-Sweep):先标记所有存活对象,再统一清理未标记区域。适合老年代中对象存活率高的场景,但易产生内存碎片,影响大对象分配
• 标记-整理(Mark-Compact):在标记-清除基础上,把所有存活对象向内存一端压缩,再清理边界外空间。解决碎片问题,但移动对象有开销,适用于老年代稳定长生命周期对象
分代收集:不是算法,而是工程级优化原则
它本身不是一种独立算法,而是将上述算法按区域分工:
• 新生代用复制算法(Minor GC 频繁、快)
• 老年代用标记-清除或标记-整理(Major GC 少、重)
• 元空间(Metaspace)基本不参与常规 GC,仅回收已卸载类的元数据
这种划分直接受益于“分代假说”——对象的年龄与存活概率强相关,不是凭空设计,而是大量真实应用统计得出的经验规律


















