serial与serial old是java最基础的单线程垃圾收集器组合,专为client模式、单核cpu、小堆(≤200mb)客户端场景设计,启用-xx:+useserialgc即可生效,日志显示defnew与tenured即确认配置成功。

Java 中的 Serial 和 Serial Old 是最基础的垃圾收集器,专为单线程环境设计,适用于客户端场景或小型应用。它们不使用多线程并发回收,所有 GC 操作(包括标记、清理、压缩)都在一个线程中完成,因此具有低开销、无同步复杂度的特点,但也意味着 GC 期间应用线程完全暂停(Stop-The-World)。
Serial 收集器:年轻代的单线程回收
Serial 是 JVM 在 Client 模式下默认的年轻代收集器(JDK 8 及以前),也适用于堆内存较小(如几十 MB)、CPU 核心数少(如单核或嵌入式设备)的场景。
- 使用复制算法回收 Eden 和 Survivor 区,GC 过程中所有应用线程暂停
- 启动参数:-XX:+UseSerialGC(同时启用 Serial + Serial Old)
- 无需额外调优参数,行为稳定可预测;适合对延迟不敏感、追求简单可靠的场景(如命令行工具、微服务中的轻量级组件)
Serial Old 收集器:老年代的单线程回收
Serial Old 是 Serial 收集器的老年代版本,采用标记-整理(Mark-Compact)算法,用于回收老年代空间。它通常与 Serial 配合使用,也可作为 CMS 收集器的后备方案(当 CMS 发生 Concurrent Mode Failure 时触发)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 每次 Full GC 都会完整遍历老年代对象,移动存活对象以消除碎片
- 由于是单线程,老年代越大,停顿时间越长;例如 512MB 老年代可能暂停数百毫秒
- 在 JDK 8 中仍可用,但 JDK 9+ 默认移除了 Client 模式,需显式指定才能启用
如何验证和观察它们的行为
可通过 JVM 启动参数开启详细 GC 日志,直观看到单线程回收特征:
- 添加:-XX:+UseSerialGC -Xloggc:gc.log -Xms128m -Xmx128m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps
- 日志中会显示类似 [DefNew: ...](DefNew 即 Serial 年轻代)和 [Tenured: ...](Tenured 即 Serial Old 老年代)
- 每次 GC 时间戳连续、无并行线程标识(如没有 “user=0.02s sys=0.00s real=0.03s” 中的多线程耗时拆分)
为什么现在很少直接使用?关键限制在哪
Serial/Serial Old 的核心局限在于无法利用多核优势,且 STW 时间随堆增长而显著上升:
- 无法并行处理:即使机器有 8 核,GC 仍只用 1 个线程,资源浪费明显
- 停顿不可控:老年代大时,Full GC 可能卡住应用一秒以上,不适合响应敏感型服务
- 无自适应策略:不支持动态调整 GC 频率、晋升阈值等,依赖人工预估堆大小和对象生命周期
- 现代替代方案更主流:如 G1(兼顾吞吐与延迟)、ZGC(超低延迟)、Parallel(高吞吐)等均基于多线程设计
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










