吞吐量优先选Parallel GC,延迟敏感选G1、ZGC或Shenandoah,内存受限场景用Serial GC或带压缩能力的收集器;需结合JDK版本、堆大小及业务SLA通过压测和GC日志验证。

选垃圾收集器不是挑最新或最炫的,而是看业务真正卡在哪——是等不起停顿,还是算不完任务,又或者内存就那么点。
吞吐量优先:后台批处理、离线计算类业务
这类服务不讲究“秒回”,但得在固定时间内干完最多活。比如日终对账、夜间报表生成、ETL数据清洗。
- 首选 Parallel GC(JDK8默认),多线程并行回收年轻代和老年代,CPU利用率拉满
- 启用参数:-XX:+UseParallelGC,可配合 -XX:GCTimeRatio=19(默认值,表示GC时间占比≤5%)控制吞吐目标
- 注意它不保证单次停顿时长,-XX:MaxGCPauseMillis只是软目标,设太小反而拖慢整体效率
延迟敏感:Web API、实时交易、用户交互型服务
用户点击下单、支付回调、搜索响应,要求STW稳定压在100ms内,甚至更低。
- 中大型在线系统推荐 G1 GC(JDK9+默认),支持大堆、可预测停顿、自动分Region管理
- 启用参数:-XX:+UseG1GC,关键调优项是 -XX:MaxGCPauseMillis=200(建议值200~400ms)
- 超高频场景(如金融行情推送、VR后端)考虑 ZGC 或 Shenandoah,停顿基本恒定在10ms内,但需JDK11+/12+且OS/CPU支持
内存受限或长期稳态运行:容器化微服务、嵌入式网关、7×24中间件
比如512MB内存限制的Spring Boot网关,或跑在ARM小板上的IoT边缘服务,既要省内存,又要防碎片OOM。
- 小堆(≤1GB)、单核或轻量级场景用 Serial GC,开销最低:-XX:+UseSerialGC
- 老年代易碎片化?选带压缩能力的收集器——G1、ZGC、Shenandoah都内置并发整理,避免Full GC飙升
- 容器环境务必确认 -XX:+UseContainerSupport 已启用(JDK10+默认),否则JVM读不到cgroup内存上限,GC策略会误判
别跳过真实验证这一步
理论匹配只是起点。对象分配速率、晋升比例、存活对象大小分布,这些动态行为只有压测才能暴露。
- 上线前必须开启GC日志:-Xlog:gc*:file=gc.log:time,tags,level(JDK11+)
- 重点观察:Minor GC频率是否过高、老年代增长是否平缓、有没有意外Full GC、停顿是否突破SLA
- 参数调优不是调数字,而是围绕业务SLA做闭环验证——比如“99%请求

















