gc参数配置需协同分代模型、回收目标与硬件特性:低延迟选g1/zgc并设停顿目标;高吞吐用parallel gc约束gc时间占比;小内存用serial;年轻代大小、survivor比例、晋升阈值需匹配对象生命周期;大对象阈值、新老代比例影响老年代压力;禁用system.gc()或改用并发触发。

GC 算法的参数设置不是孤立调某个开关,而是围绕“分代模型+回收目标+硬件特性”协同配置。选对算法是前提,配准参数才是落地关键。
按业务目标选收集器类型
不同收集器面向不同优化方向,不能只看“新”或“快”:
-
低延迟敏感型(如支付、实时推送):优先选 G1 或 ZGC,用
-XX:+UseG1GC或-XX:+UseZGC;G1 需配合-XX:MaxGCPauseMillis=200设定停顿目标(实际通常在 100–300ms 区间) -
高吞吐量优先型(如批处理、报表生成):用 Parallel GC,启用
-XX:+UseParallelGC+-XX:+UseParallelOldGC,再通过-XX:GCTimeRatio=19(即 GC 时间占比 ≤ 5%)约束吞吐量 -
老系统或小内存场景(如嵌入式、单核服务器):Serial 收集器仍适用,用
-XX:+UseSerialGC,避免多线程调度开销
新生代参数要匹配对象生命周期
年轻代配置直接影响 Minor GC 频率和对象晋升行为:
-
-Xmn决定 Eden + Survivor 总大小;设为堆的 1/2~1/3(如 -Xmx4g 时,-Xmn1.5g 较稳妥),过小会导致频繁 Minor GC,过大则推高 Full GC 压力 -
-XX:SurvivorRatio=8表示 Eden : 一个 Survivor = 8:1,即两个 Survivor 共占年轻代 1/5;若观察到 Survivor 区总溢出(GC 日志中出现 “to-space overflow”),可适当调大比例(如设为 6)或启用-XX:+UseAdaptiveSizePolicy让 JVM 动态调整 -
-XX:MaxTenuringThreshold控制对象晋升年龄,默认 15;若大量对象活不过 3 次 GC,设为 3 可减少 Survivor 复制次数;设为 0 则直接晋升老年代(慎用,易加剧老年代压力)
老年代与大对象策略需联动设置
避免对象“误入”或“卡死”老年代:
-
-XX:PretenureSizeThreshold设置大对象直接进老年代的阈值(单位字节),例如-XX:PretenureSizeThreshold=1048576(1MB);适用于已知会分配超大数组或缓存块的场景 - 老年代空间不足常引发 Full GC,可通过
-XX:NewRatio=2显式设新生代:老年代 = 1:2(默认是 2:1),但需结合-Xms/-Xmx统一规划,避免老年代碎片化 - CMS 已废弃,G1/ZGC 默认支持并发回收;若仍在用 CMS,必须配
-XX:+UseConcMarkSweepGC+-XX:CMSInitiatingOccupancyFraction=70(提前在老年代占用达 70% 时启动回收),否则易触发 Concurrent Mode Failure
禁用或干预 System.gc() 的实际影响
代码中显式调用 System.gc() 多数时候有害无益:
- 默认会触发 Full GC,打断正常回收节奏;可用
-XX:+DisableExplicitGC彻底禁用 - 若必须保留主动触发能力(如资源密集型任务结束时),加
-XX:+ExplicitGCInvokesConcurrent,让 G1/CMS 改走并发路径,降低 STW 时间 - 注意:它对 DirectByteBuffer 等堆外内存完全无效,这类内存需靠
buffer.cleaner().clean()或 try-with-resources 自动释放











