Serial Old 收集器采用单线程标记-整理算法,不支持并行并发,优化需通过参数调优(如-XX:NewRatio、-XX:MaxTenuringThreshold)和应用设计(减少长生命周期对象、及时释放引用)来缓解停顿,而非算法改进。

Serial Old 收集器使用的是标记-整理(Mark-Compact)算法,它本身不支持并行或并发优化,也不具备现代 GC 的自适应调优能力。所谓“优化老年代”,实际是指在 Serial Old 的约束下,通过合理配置和应用设计来缓解其性能瓶颈。
理解 Serial Old 的工作方式
Serial Old 是单线程、基于标记-整理的老年代收集器,适用于 Client 模式或小内存、低负载场景。它会暂停所有应用线程(Stop-The-World),依次执行:
- 标记阶段:遍历 GC Roots,标记所有可达对象;
- 整理阶段:将存活对象向内存一端移动,消除碎片,再清理边界外的内存。
由于是单线程且必须移动对象,老年代越大、存活对象越多,停顿时间越长——这是无法靠“算法改进”规避的本质限制。
通过 JVM 参数控制老年代行为
Serial Old 本身不可配置算法逻辑,但可通过参数影响其触发时机和压力分布:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- 减小 -Xms 和 -Xmx 差距,避免老年代动态扩容带来的额外整理开销;
- 适当调大 -XX:NewRatio(如设为 3 或 4),让老年代初始空间更充足,降低 Minor GC 晋升压力;
- 用 -XX:MaxTenuringThreshold 控制对象晋升年龄,避免过早或过晚进入老年代;
- 启用 -XX:+UseAdaptiveSizePolicy(虽对 Serial 影响有限,但可辅助新生代调优,间接减少老年代负担)。
从应用侧减少老年代压力
Serial Old 的停顿敏感度高,最有效的“优化”来自减少它需要处理的对象:
- 避免长生命周期对象(如静态缓存、未关闭的连接池)长期驻留老年代;
- 用对象池替代频繁创建/销毁的中等生命周期对象(注意权衡维护成本);
- 及时置 null 引用、释放大数组或大集合,尤其在 long-running 方法末尾;
- 监控 jstat -gc 中的 OGC(Old Generation Capacity) 和 OU(Old Used),识别异常晋升或内存泄漏。
明确替代路径比硬调 Serial Old 更现实
Serial Old 本质是历史兼容方案。若老年代回收成为瓶颈,说明应用已超出其适用范围:
- 升级到 Server 模式,默认启用 Parallel Old(并行标记-整理);
- 堆大于 4GB 时,考虑 CMS(已废弃)或 G1 / ZGC / Shenandoah 等低延迟收集器;
- 确认是否误用 -XX:+UseSerialGC——该参数会强制启用 Serial + Serial Old,即使在服务端也应谨慎。
真正需要“优化 Serial Old 老年代”的场景极少,多数情况是选型或配置偏差所致。

















