hotspot jvm垃圾收集器按“串行→并行→并发→低延迟”代际演进,分别聚焦小内存、高吞吐、低延迟和确定性停顿,每代解决前代瓶颈:串行(serial/serial old)单线程stw,适合客户端;并行(parnew/parallel scavenge等)多线程stw提升吞吐;并发(cms)部分阶段与用户线程并发,降低延迟但有碎片和浮动垃圾问题;低延迟(g1/zgc/shenandoah)通过region化、读屏障等实现毫秒级可控停顿。

HotSpot JVM 的垃圾收集器不是凭空出现的,而是围绕“停顿时间(Latency)”和“吞吐量(Throughput)”两大核心目标,分阶段演进出来的四类技术路线:串行 → 并行 → 并发 → 低延迟。它们不是并列关系,而是代际递进——每一代都在解决前一代的关键瓶颈。
串行家族:单线程、极简可靠,面向小内存场景
代表收集器:Serial(新生代)、Serial Old(老年代)
这是 JVM 最原始的 GC 实现,诞生于 JDK 1.3 之前。它用一条线程完成全部 GC 工作,全程 STW(Stop-The-World),但正因为“单”,所以没有线程调度、同步、通信开销,内存占用最小、启动最快。
适用场景非常明确:客户端模式、嵌入式环境、几十 MB 级堆内存应用(如 Swing 桌面工具、小型 IoT 终端)。在这些场景里,GC 停顿常在毫秒级,用户几乎无感,而省下的资源比多线程更实在。
- 默认启用条件:JVM 自动识别为 Client 模式时(如 -client 参数,或早期 JDK 默认行为)
- 手动启用:-XX:+UseSerialGC
- 关键价值:不是“落后”,而是“精准克制”——在资源受限时,拒绝过度设计
并行家族:多线程加速吞吐,面向后台计算密集型负载
代表收集器:ParNew、Parallel Scavenge(新生代),Parallel Old(老年代)
随着服务器硬件升级(多核 CPU 普及),单线程 GC 成为瓶颈。并行收集器应运而生——它仍要求 STW,但把 GC 任务拆给多个线程并行执行,显著缩短单次回收耗时,从而提升整体吞吐量。
这里要注意区分两个“并行”分支:
- ParNew:Serial 的多线程翻版,设计初衷是配合 CMS(因 CMS 需要一个能快速完成新生代回收的搭档),强调与 CMS 的兼容性
- Parallel Scavenge + Parallel Old:专为吞吐量优化,支持 -XX:MaxGCPauseMillis 和 -XX:GCTimeRatio 等量化调控,并自带自适应策略(-XX:+UseAdaptiveSizePolicy),适合批处理、科学计算等对响应不敏感、但要求长时间高效率运行的系统
并发家族:突破 STW 边界,首次实现用户线程与 GC 线程“共存”
代表收集器:CMS(Concurrent Mark-Sweep)
当 Web 应用、实时交易系统等对延迟极度敏感时,并行 GC 的“全暂停”模型已不可接受。CMS 在 JDK 5 引入,首次将 GC 拆分为“初始标记(STW)、并发标记、重新标记(短暂停)、并发清除”四阶段,其中两段核心工作(标记、清除)与用户线程并发执行。
但它不是银弹:
- 对 CPU 资源争抢明显,可能拖慢业务吞吐
- 采用“标记-清除”算法,易产生内存碎片,触发 Full GC
- 无法处理“浮动垃圾”,并发期间新分配对象若在清除后才死亡,只能等下次回收
CMS 的意义不在于完美,而在于证明了“可预测低延迟 GC”可行——它直接催生了后续 G1 和 ZGC 的设计哲学。
低延迟家族:以确定性停顿为目标,面向现代云原生与实时系统
代表收集器:G1(JDK 7u4)、ZGC(JDK 11)、Shenandoah(JDK 12)
这一代不再满足于“减少停顿”,而是追求“停顿可控且与堆大小无关”。G1 将堆划分为固定大小 Region,优先回收垃圾最多的区域(Garbage-First),配合增量式并发标记与混合回收,把 STW 控制在 10~200ms;ZGC 和 Shenandoah 更进一步,通过读屏障(Load Barrier)和染色指针等技术,将 STW 压缩到 10ms 以内,甚至亚毫秒级,且停顿时间不随堆增长而上升。
- G1 是过渡主力:平衡性好,JDK 9 后成为默认 GC,适合中大型服务(几 GB 到数十 GB 堆)
- ZGC/Shenandoah 是前沿选择:适用于超大堆(TB 级)、金融风控、游戏服务器等毫秒级响应刚需场景
- 共同特征:不再严格区分新生代/老年代,Region 化 + 并发标记 + 增量转移,彻底重构 GC 工作模型











