Serial 串行、Parallel 并行、CMS 并发收集器

一、Serial 串行垃圾回收器

1. 定义与运行机制

Serial 是最基础、单线程垃圾收集器,分为Serial Young(新生代)+ Serial Old(老年代)

  1. 全程只有1 条 GC 线程执行垃圾回收;
  2. 只要开始 GC,全部业务用户线程 STW 暂停,GC 完成后业务线程才能恢复;
  3. 新生代使用复制算法,老年代使用标记 - 压缩算法。

2. 特点

  1. 单线程回收,没有多线程竞争,内存开销极小;
  2. 简单高效,资源占用低,适合 CPU 核心少的机器;
  3. STW 停顿时间长,堆越大,停顿越严重。

3. 适用场景

  1. JDK 客户端模式默认收集器;
  2. 单核、双核低配置机器、嵌入式设备;
  3. 堆内存很小的小程序、本地测试工具。

二、Parallel 并行垃圾回收器(Parallel GC)

1. 定义与运行机制

全称 Parallel Throughput,JDK 服务端默认收集器,分为 Parallel Young + Parallel Old。

  1. GC 阶段使用多条 GC 线程并行工作,充分利用多核 CPU;
  2. GC 期间依然会全部用户线程 STW 暂停,只是 GC 内部多线程提速;
  3. 新生代复制算法,老年代标记压缩;
  4. 核心目标:最大化吞吐量(吞吐量 = 业务运行时间 / 总运行时间)。

2. 特点

  1. 多核机器下 GC 速度远快于 Serial;
  2. 可设置吞吐量目标,JVM 自动调整堆大小、GC 频率;
  3. 牺牲停顿时间换取吞吐量,不控制单次 STW 时长,大堆下单次停顿会很久。

3. 适用场景

  1. 后台批处理、大数据离线任务;
  2. 对响应延迟不敏感、追求高吞吐量的业务;
  3. JDK8 之前服务端默认收集器。

三、CMS 并发标记清除收集器(Concurrent Mark Sweep)

1. 定义与运行机制

CMS 是第一款并发低延迟 收集器,只负责老年代回收,新生代搭配 Parallel Young 使用。 核心设计:GC 标记阶段和用户业务线程并发执行,大幅缩短 STW 暂停时间。 整体分为 6 个阶段,只有 3 个阶段会 STW:

  1. 初始标记(STW):快速标记 GC Roots 直接可达对象;
  2. 并发标记(不暂停):GC 线程和业务线程同时运行,遍历所有存活对象;
  3. 并发预清理(不暂停);
  4. 重新标记(STW):修正并发阶段新增 / 变动的引用,防止漏标;
  5. 并发清理(不暂停):并行回收垃圾对象;
  6. 并发重置(不暂停):清空标记数据,准备下一次 GC。

2. 核心特点与痛点

优点
  1. 大部分阶段并发执行,STW 停顿很短,追求低延迟;
  2. 适合需要快速响应的线上业务。
致命缺点(面试高频考点)
  1. 标记清除算法,产生大量内存碎片;内存碎片化严重时,分配大对象失败,直接触发 Full GC;
  2. 并发失败:并发清理时堆内存占用过快,预留空间不足,CMS 无法完成并发回收,退化串行 Full GC,长时间 STW;
  3. 需要预留一部分堆内存给并发 GC 使用,内存利用率低;
  4. 维护三色标记、浮动垃圾,带来额外 CPU 开销。

3. 适用场景

  1. 互联网线上业务、接口服务,要求低延迟、短 GC 停顿;
  2. JDK8 广泛使用,JDK9 后被 G1 替代,JDK14 彻底废弃 CMS。

四、三者核心横向对比(面试加分)

表格

收集器 GC 线程 用户线程 STW 核心目标 算法 主要缺陷
Serial 串行 单线程 GC GC 全程暂停 最小内存开销 复制 + 标记压缩 多核机器 GC 速度慢,停顿久
Parallel 并行 多线程 GC GC 全程暂停 最大化吞吐量 复制 + 标记压缩 不控制停顿,大堆 STW 很长
CMS 并发 多线程 GC,标记 / 清理与业务并发 仅初始、重新标记短暂暂停 低延迟、短 STW 标记清除 内存碎片、并发失败、浮动垃圾

五、一句话总结收尾

Serial 单线程、资源消耗最低,适合小内存单核设备;Parallel 多线程并行回收,追求高吞吐量,适合离线批处理;CMS 实现 GC 与业务线程并发,大幅缩短 STW 停顿,主打低延迟,但存在内存碎片、并发失败等问题,后续被 G1 替代。

相关推荐
Diligently_2 小时前
Anolis 系统更新与密码设置&磁盘扩容
java·后端·spring
mqiqe2 小时前
线程调度与 Schedulers:Project Reactor 并发模型的核心引擎
java·开发语言·网络
我命由我123452 小时前
Android 开发问题:unexpected element <service> found in <manifest>
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
正在走向自律2 小时前
飞算JavaAI能搞定充电站故障处置吗?
java·ai编程·java开发·飞算javaai·java代码生成·ai coding模型·springboo
用户40966601317512 小时前
Guava 不止有 Lists 和 Maps:Cache、EventBus、Multimap 实战
java·后端
xixiaoyunya3 小时前
JavaScript 异步编程全解析:从回调地狱到 async/await 的演进之路
开发语言·javascript·ecmascript
一只叫煤球的猫3 小时前
从 Java 21 到 Java 25:ThreadLocal 以外的选择—— ScopedValue
java·后端·架构
精英的英3 小时前
记一次 Qt5 Language Server 开发
开发语言·vscode·qt
步行cgn3 小时前
MyBatis 多对一关联映射详解
java
仍然.3 小时前
SpringCloud---Eureka介绍
java·spring cloud·eureka