吞吐量优先应选Parallel GC,因其全程STW、无协调开销、多线程并行且开箱即用;延迟敏感场景首选G1GC(目标≤200ms),需合理设MaxGCPauseMillis并配合RegionSize调优;小内存系统仍适用Serial GC;ZGC/Shenandoah适用于大堆低延迟但有JDK和运行环境限制。

吞吐量优先和延迟优先不是非此即彼的标签,而是业务对GC行为的核心诉求。选错收集器,轻则任务变慢、资源浪费,重则接口超时、用户流失。关键不在“新旧”,而在“匹配”。
吞吐量优先:Parallel GC 是默认且高效的选择
批处理、离线计算、定时任务等场景,目标是单位时间完成最多工作,允许单次停顿稍长(几百毫秒甚至秒级)。Parallel GC 就是为此而生:
- 全程 STW,但无并发协调开销,单次回收效率高;
- 多线程并行执行,天然适配多核 CPU;
- 开启 -XX:+UseParallelGC 即启用吞吐模式,无需额外调参;
- 堆大于 8GB 且 CPU ≥8 核时,建议设 -XX:ParallelGCThreads=物理核数×5/8,避免线程争抢;
- G1GC 在纯吞吐场景下反而可能拖慢整体进度——它的并发标记、Region 管理等机制带来额外开销,不必要。
延迟敏感:G1GC 是当前最稳妥的平衡点
Web API、网关、实时推荐等服务,用户对卡顿极其敏感。G1GC 不承诺硬实时,但能以可预测的方式逼近软实时目标(如 ≤200ms):
- -XX:MaxGCPauseMillis=200 是生产推荐起点,过低(如 50ms)会导致频繁并发标记和混合回收,反而加剧抖动;
- 必须配合 -XX:G1HeapRegionSize 调整大对象阈值,防止 Humongous 分配打乱回收节奏;
- 通过 -Xlog:gc*:file=gc.log 观察每次 Evacuation Pause 实际耗时分布,而非只看平均值;
- 堆小于 4GB 时,G1 的 Region 管理开销反而高于 ParNew+CMS(JDK8 及以下),此时不推荐 G1。
小内存单机系统:Serial GC 依然不可替代
堆 ≤1GB 的后台管理系统、内部工具、嵌入式 Java 应用,CPU 核心少、请求量低、GC 频率极低:
- 单线程回收,无同步/通信开销,内存占用最小;
- 几十毫秒级 STW 对业务完全无感;
- 无需调参,-XX:+UseSerialGC 开箱即稳;
- 在 Client 模式或资源受限容器中仍是首选。
ZGC / Shenandoah:面向大堆与强低延迟,但有明确前提
它们宣传“停顿与堆大小无关”,成立条件很具体:
- 要求分配速率稳定,不能突发大量大对象;
- ZGC 需 Linux 64-bit + JDK 17+(生产环境强烈建议);Shenandoah 在 JDK 16+ 才默认启用;
- 都不支持关闭压缩指针(-XX:-UseCompressedOops)的大堆(>4TB);
- 真实瓶颈常不在 GC 本身,而在安全点同步、Reference 处理积压、元空间卡顿等“非 GC 停顿”上。

















