了解 JVM 垃圾回收的基本原理与作用
掌握主流垃圾回收器的类型、特点及适用场景
学会通过 JVM 参数配置和优化垃圾回收行为
理解不同垃圾回收器在线程使用和暂停时间上的差异
JVM 垃圾回收(Garbage Collection, GC)是 Java 内存管理的核心机制。它自动识别并释放堆中不再被引用的对象所占用的内存,从而防止内存泄漏、提升程序性能。JVM 使用 标记 - 清除(Mark and Sweep) 算法作为基础,通过追踪活跃对象并回收不可达对象的内存空间。
多线程垃圾回收器(如 Parallel GC)允许我们指定用于 GC 的线程数:
java -XX:+UseParallelGC -XX:ParallelGCThreads=4 -jar MyApp.jar
ParallelGCThreads的值通常设置为 CPU 核心数,但可根据应用负载调整。
对于对延迟敏感的应用,可通过以下参数限制最大 GC 暂停时间(单位:毫秒):
java -XX:+UseParallelGC -XX:MaxGCPauseMillis=200 -jar MyApp.jar注意:该参数是“目标”而非硬性保证,JVM 会尽力满足,但不保证绝对达成。
最简单的 GC 实现
使用 单线程 执行所有 GC 工作
GC 期间 完全暂停应用线程(Stop-The-World)
适用于 小型应用 或 嵌入式系统(内存资源有限)
启用方式:
java -XX:+UseSerialGC -jar MyApp.jar吞吐量优先
Java 8 的默认 GC
又称 吞吐量收集器
使用 多个线程 并行执行 GC,充分利用 CPU 资源
适合 批处理、后台任务 等可容忍暂停的高性能场景
与 Serial GC 的核心区别:
Serial:单线程,简单但慢
Parallel:多线程,更快,但仍有 STW 暂停(包括 Minor GC)
启用方式(Java 9+ 需显式指定):
java -XX:+UseParallelGC -jar MyApp.jar目标:最小化暂停时间
大部分工作 与应用线程并发执行
仅在以下两个阶段暂停应用:
初始标记(Initial Mark)
重新标记(Remark)
适用于 低延迟要求 的场景,如 Web 服务器、实时交互系统
与 Parallel GC 的关键区别:
Parallel:追求吞吐量,暂停时间较长
CMS:追求低延迟,允许应用在 GC 期间继续运行
注意:CMS 自 Java 14 起已被 弃用,Java 17 中 彻底移除
启用方式(旧版本 JDK):
java -XX:+UseConcMarkSweepGC -jar MyApp.jarJDK 7 引入,Java 9 起成为默认 GC
专为 大堆内存(> 4 GB) 设计
将堆划分为 多个等大区域(Region,1 MB ~ 32 MB)
采用 “垃圾优先”策略:优先回收垃圾最多的 Region
支持 堆内存压缩,避免碎片化
优势:
可预测的暂停时间
高吞吐与低延迟兼顾
替代了 CMS 成为主流选择
启用方式(Java 8 及更早版本):
java -XX:+UseG1GC -jar MyApp.jarJava 9+ 默认即为 G1,无需显式开启。
Java 11 引入(实验性),Java 15 转正
超低延迟 GC,暂停时间通常 < 10 毫秒
支持 TB 级堆内存
几乎全程并发执行,对应用影响极小
适用场景:对延迟极度敏感的大型应用(如金融交易、实时分析)
启用方式:
java -XX:+UseZGC -jar MyApp.jarJava 12 引入(OpenJDK 特有)
与 ZGC 类似,目标是 极低暂停时间
通过 并发压缩 实现高效内存回收
暂停时间与堆大小 无关
启用方式:
java -XX:+UseShenandoahGC -jar MyApp.jar注意:Shenandoah 在 Oracle JDK 中默认不可用,需使用 OpenJDK 构建版本。

Serial GC:适合小型应用,资源消耗最低。
Parallel GC:默认于 Java 8,强调吞吐量,适合后台任务。
CMS:已淘汰,曾用于低延迟场景。
G1 GC:现代应用首选,兼顾吞吐与延迟,Java 9+ 默认。
ZGC / Shenandoah:面向未来,支持超大堆与毫秒级暂停,适用于高实时性系统。
通过 JVM 参数可灵活控制 GC 行为,包括线程数、暂停目标、堆大小等。
为什么 CMS 垃圾回收器最终被 G1 取代?从内存碎片和维护复杂度角度分析。
在一个需要处理 64 GB 堆内存且要求 99% 的 GC 暂停时间低于 10 毫秒的系统中,应选择哪种垃圾回收器?为什么?
如果你的应用部署在 Docker 容器中,仅分配了 2 GB 内存,你会优先考虑哪种 GC?如何通过 JVM 参数优化其行为?