要使用 parallel scavenge 和 parallel old 实现高吞吐量 gc,需启用 -xx:+useparallelgc(java 8+ 自动启用两者),设 -xx:gctimeratio=99 或更大以控制 gc 时间占比,固定堆大小(-xms=-xmx),新生代占 30%–40%,并通过 gc 日志和 jstat 验证吞吐量。

要使用 Parallel Scavenge(新生代)和 Parallel Old(老年代)组合实现高吞吐量 GC,关键在于显式启用该组合,并合理设置吞吐量目标与堆大小参数。
启用 Parallel Scavenge + Parallel Old 组合
Java 8 及以后版本中,-XX:+UseParallelGC 会同时启用 Parallel Scavenge(用于新生代)和 Parallel Old(用于老年代),无需额外指定老年代收集器。这是 JVM 默认推荐的高吞吐量组合。
- 不要混用:-XX:+UseParallelGC 与 -XX:+UseParallelOldGC 功能重叠,后者在 Java 8+ 已被自动包含,单独加不报错但冗余
- 避免冲突:不能与 -XX:+UseG1GC、-XX:+UseZGC 等其他 GC 器共用,否则 JVM 启动失败
- 验证是否生效:启动时加 -XX:+PrintGCDetails -Xloggc:gc.log,日志中出现
PSYoungGen和ParOldGen即表示启用成功
设定吞吐量目标(核心调优点)
Parallel 收集器通过 -XX:MaxGCPauseMillis(目标停顿)和 -XX:GCTimeRatio(吞吐量比例)协同工作,但高吞吐量场景应优先使用后者。
- -XX:GCTimeRatio=N 表示“应用线程运行时间 / GC 时间 ≥ N/(N+1)”;例如设为 99,即允许 GC 占用 ≤ 1% 的总时间(99/100)
- 默认值是 99(对应 1% GC 时间),若系统 CPU 富余且业务对延迟不敏感,可保持默认或设为更大值(如 199 → ≤0.5% GC 时间)
- 慎用 -XX:MaxGCPauseMillis:它会触发自适应堆调整(如缩小年轻代),反而可能降低吞吐量;高吞吐量场景建议不设或设得较宽松(如 200ms 以上)
合理配置堆与分代大小
Parallel 收集器具备自适应调节能力(UseAdaptiveSizePolicy),但初始设置仍影响启动期性能和稳定性。
- 用 -Xms 和 -Xmx 设为相同值(如 -Xms4g -Xmx4g),避免运行时扩容带来额外开销,利于吞吐量稳定
- 新生代占比建议 30%–40%,可通过 -XX:NewRatio=2(老:新 = 2:1,即新生代占 1/3)或 -Xmn1200m 显式指定
- 避免过小新生代:易引发频繁 Minor GC 和晋升压力;避免过大:导致单次 Minor GC 延长,且可能浪费内存
监控与调优验证
仅靠参数不足以保证高吞吐量,需结合实际运行指标判断效果。
- 关注 GC 日志中的 GC throughput(如 “2176384K->124288K(2621440K), 0.0921230 secs]” 后的总耗时与总 GC 时间比)
- 用 jstat -gc
查看 YGCT/YGCT(年轻代 GC 总耗时)、FGCT(Full GC 耗时)和 GCT(总 GC 时间),计算 GCT / (运行时间) 是否满足目标 - 若 Full GC 频繁发生,说明老年代压力大,需检查对象晋升行为(如过早晋升、内存泄漏),而非单纯调大堆
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











