新生代和老年代的 GC 算法有哪些?
2026年02月24日
一则或许对你有用的小广告
欢迎 加入小哈的星球 ,你将获得: 专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目: 《Spring AI 项目实战(问答机器人、RAG 增强检索、联网搜索)》 正在持续爆肝中,基于
Spring AI + Spring Boot3.x + JDK 21..., 点击查看; - 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot3.x + JDK 17..., 点击查看项目介绍; 演示链接: http://116.62.199.48:7070/; - 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/
面试考察点
- 考察对 JVM 垃圾收集(GC)基本原理的理解:面试官想知道你是否清楚 JVM 为什么采用分代收集(Generational Collection)以及不同代的特点。
- 考察对具体 GC 算法的掌握程度:不仅仅是知道算法名字,更要理解其核心思想、工作原理以及优缺点。
- 考察算法与具体垃圾收集器的关联能力:面试官希望你能将抽象的算法与实际的垃圾收集器(如 Serial、Parallel、CMS、G1)对应起来,知道哪些收集器在新生代/老年代使用了什么算法。
- 考察对 GC 发展趋势的认知:通过你对 G1、ZGC 等新收集器的了解,判断你是否关注 JVM 的最新演进。
核心答案
JVM 的新生代和老年代分别采用不同的垃圾收集算法,以适应各自区域的对象存活率和内存布局特点。
- 新生代(Young Generation):主要采用 复制算法(Copying)。因为新生代对象 “朝生夕死”,存活率低,复制算法只需复制少量存活对象,效率高且不会产生内存碎片。
- 老年代(Old Generation):主要采用 标记-清除算法(Mark-Sweep) 或 标记-整理算法(Mark-Compact)。老年代对象存活率高,复制算法不划算,所以通过标记来识别垃圾,然后直接清除或进行内存整理。
深度解析
1. 新生代复制算法详解
- 原理:将内存分为一块较大的 Eden 空间和两块较小的 Survivor 空间(默认比例 8:1:1)。每次使用 Eden 和其中一块 Survivor(From)。回收时,将 Eden 和 From 中存活的对象复制到另一块 Survivor(To),然后一次性清理掉 Eden 和 From 空间。如果 To 空间不够,存活对象会通过 分配担保 直接进入老年代。
- 优点:实现简单,运行高效,不会产生内存碎片。
- 缺点:需要预留一块空闲的 Survivor 作为复制目标,存在空间浪费;对象存活率较高时,复制操作开销变大。
- 具体收集器:
- Serial / ParNew:均采用这种典型的复制算法。
- Parallel Scavenge:也是复制算法,但更注重吞吐量控制。
2. 老年代标记-清除与标记-整理算法
- 标记-清除(Mark-Sweep)
- 原理:先标记出所有存活对象,然后统一回收未被标记的对象。
- 优点:实现简单,不需要移动对象。
- 缺点:会产生大量内存碎片,导致后续大对象分配失败而提前触发 Full GC;标记和清除两个过程的效率都不高。
- 代表收集器:CMS(Concurrent Mark Sweep) 老年代收集器基于标记-清除算法。
- 标记-整理(Mark-Compact)
- 原理:标记阶段与标记-清除相同,但后续不是直接清除,而是将所有存活对象向内存一端移动,然后直接清理边界以外的内存。
- 优点:解决了内存碎片问题,内存利用率高,分配大对象更顺畅。
- 缺点:移动对象需要暂停用户线程(Stop The World),如果老年代对象很多,停顿时间可能较长。
- 代表收集器:
- Parallel Old:老年代采用标记-整理算法,与 Parallel Scavenge 搭配追求高吞吐量。
- Serial Old:同样采用标记-整理算法。
3. 新趋势:分区收集器中的算法演变
- G1(Garbage First)收集器:虽然保留了新生代和老年代的概念,但物理上不再连续,而是将堆划分为多个大小相等的 Region。G1 整体上采用 标记-整理算法,从局部(两个 Region 之间)看又是复制算法。它避免了在整个老年代进行整理,从而降低了停顿时间。
- ZGC(Z Garbage Collector):同样基于 Region 布局,通过染色指针和读屏障等技术实现几乎全部的并发收集,其核心算法也融合了复制和标记的思想,但实现细节更为复杂。
4. 常见误区
- 误区一:认为所有垃圾收集器都严格区分新生代和老年代算法。
- 实际上,像 G1、ZGC 这种新一代收集器,虽然仍然有分代逻辑(G1 明确分代,ZGC 在后续版本中也开始支持分代),但算法实现已经高度融合,不再是简单的“新生代只用复制、老年代只用标记-整理”。
- 误区二:混淆 “标记-清除” 与 “标记-整理” 的适用场景。
- 如果老年代使用 CMS(标记-清除),必须预留足够空间或搭配备用方案(如启用
-XX:+UseCMSCompactAtFullCollection),否则碎片问题可能引发频繁 Full GC。
- 如果老年代使用 CMS(标记-清除),必须预留足够空间或搭配备用方案(如启用
总结
JVM 通过分代收集,让新生代利用复制算法的高效处理短期对象,让老年代利用标记-清除或标记-整理算法应对长期存活对象。理解这些基础算法,是掌握各种垃圾收集器工作原理的基石,也是 JVM 性能调优的必备知识。