说一下Java的垃圾回收机制

Java 的垃圾回收(Garbage Collection,简称 GC)是 JVM(Java 虚拟机)自动内存管理的最核心机制之一,它让开发者不用手动释放内存(不像 C/C++ 需要 free/delete),极大降低了内存泄漏和野指针的风险。

下面按逻辑顺序给你讲清楚目前(JDK 8 → JDK 21+ / 2025-2026 主流版本)的垃圾回收机制:

1. 核心问题:怎么判断一个对象是“垃圾”?

主流判定方式(也是现在几乎全部 GC 都用的):

可达性分析算法(Reachability Analysis)

  • 从一系列叫 GC Roots 的对象开始向下搜索
  • 能被搜索到的对象 → 存活
  • 搜索不到的对象 → 垃圾(可回收)

常见的 GC Roots(2025 年仍然是这些):

  • 虚拟机栈(栈帧中的本地变量表)中引用的对象
  • 方法区中类静态属性引用的对象
  • 方法区中常量池中引用的对象
  • 本地方法栈中 JNI(Native 方法)引用的对象
  • 已启动且未停止的 Java 线程对象
  • ……

注意引用计数法早就被主流 JVM 抛弃了(因为循环引用问题很难解决)。

2. 分代收集理论(Generational Collection)——目前最核心的设计思想

绝大部分对象“朝生夕死”,少数对象能活得很久。

基于这个弱分代假说,JVM 把堆内存分为:

区域存放对象特点存活时间常用回收算法GC 类型频率
Eden新创建的对象很短Minor GC很高
Survivor经过 1 次 Minor GC 仍存活较短复制算法Minor GC较高
Old/Tenured经过多次 Minor GC 仍存活、被显式晋升很长标记-清除 / 标记-整理Major/Full GC较低
Metaspace (JDK8+)类元数据、常量池等很长

年轻代(Young Generation) = Eden + 两个 Survivor(From / To)

老年代(Old Generation) = 除了年轻代以外的堆空间

3. 主流 GC 算法(组合使用)

算法名称是否会产生 STW(Stop The World)是否移动对象(整理)适用场景内存碎片情况备注
标记-清除老年代最基础
标记-整理老年代老年代整理用
复制是(复制到另一半)年轻代(Eden → Survivor)空间浪费一半
标记-复制年轻代现代年轻代主流

4. 2025-2026 年主流垃圾收集器对比(最常用)

收集器年轻代算法老年代算法是否并发最大暂停时间目标适用场景JDK 默认(21+)当前推荐度(2026)
Serial复制标记-整理客户端、小内存单核很低
Parallel复制标记-整理吞吐量优先、批处理任务中等
CMS复制标记-清除(并发)响应时间敏感(已被 G1 取代)很低(已废弃)
G1复制标记-清除+整理(并发为主)可设置(默认200ms)服务端、大多数场景(默认)JDK9+ 默认★★★★☆
ZGC复制并发标记+并发整理<10ms(目标<1ms)超大堆、低延迟(8GB–16TB+)JDK21+ 渐强★★★★★(推荐)
Shenandoah复制并发标记+并发整理<10ms低延迟、对吞吐量要求不高★★★★☆
Epsilon无 GC无 GC内存确定不会耗尽的极致场景特殊用途
Generational ZGC复制(分代)并发整理(分代)<1–2msJDK21+ 最新低延迟方案★★★★★(最强趋势)

5. 简单总结目前(2025-2026)最推荐的选择逻辑

  • 普通 Web / 中小型服务G1(-XX:+UseG1GC)仍然是最稳妥默认选择
  • 大内存(>8GB)、对延迟敏感(99 分位延迟 <10ms)→ Generational ZGC(-XX:+UseZGC -XX:+ZGenerational)
  • 极致吞吐量、不太在乎延迟 → Parallel(-XX:+UseParallelGC)
  • 超低延迟实验性场景 → Shenandoah 或 ZGC(非分代)

一句话总结现代 Java GC 趋势:

从“吞吐量优先”(Parallel → CMS → G1) → 转向 “低延迟优先 + 可接受的吞吐量损失”(ZGC / Shenandoah / Generational ZGC)

有具体场景(比如微服务、游戏服务器、大数据、超低延迟交易系统等)的话,可以告诉我,我再帮你推荐最合适的收集器组合和常用调优参数~

文章已创建 4138

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部