Skip to content

Serial/Serial Old 回收器

最古老也是最可靠的收集器

Serial 是 JVM 最古老的垃圾回收器,从 Java 1.3 开始就存在。它用单线程进行垃圾回收,简单、高效、可靠。

Serial 收集器的工作原理

年轻代:Serial(复制算法)

┌─────────────────────────────────────────────┐
│              Serial 年轻代收集                    │
│                                             │
│  线程:单线程(Stop-The-World)             │
│  算法:复制算法                               │
│  停顿:较长(需要暂停所有应用线程)            │
│                                             │
│  Eden ──满──▶ MinorGC ──▶ 存活对象复制到 S0  │
│       ───────────────────────────────▶     │
│                                             │
│  特点:                                        │
│  - 单线程执行                                  │
│  - 简单高效(没有线程同步开销)                  │
│  - 适合单核或低配机器                           │
└─────────────────────────────────────────────┘

老年代:Serial Old(标记-压缩算法)

┌─────────────────────────────────────────────┐
│              Serial Old 老年代收集               │
│                                             │
│  线程:单线程(Stop-The-World)             │
│  算法:标记-压缩                               │
│  停顿:最长(整理大量存活对象)                 │
│                                             │
│  老年代满 ──满──▶ FullGC ──▶ 标记-压缩       │
│                                             │
│  特点:                                        │
│  - 单线程执行                                  │
│  - CMS 失败时的备选方案                         │
│  - 作为老年代收集器时,停顿时间很长              │
└─────────────────────────────────────────────┘

Serial 的使用

bash
# 启用 Serial 收集器
java -XX:+UseSerialGC MyApp

# 等价于:
# 年轻代:Serial(复制)
# 老年代:Serial Old(标记-压缩)

Serial 的参数配置

bash
# 年轻代
java -XX:+UseSerialGC \
     -Xms256m \           # 初始堆
     -Xmx256m \           # 最大堆
     -Xmn128m \           # 年轻代大小
     -XX:SurvivorRatio=8  # Eden:Survivor = 8:1

# 老年代
# Serial Old 无太多可调参数(简单设计)

Serial 的优缺点

优点缺点
简单高效(无线程同步开销)停顿时间长
内存占用小(无额外数据结构)单核利用
适合低配机器吞吐量低
适合短期程序不适合服务器

Serial 与其他收集器的对比

维度SerialThroughput(Parallel)CMS
线程数单线程多线程并行多线程并发
停顿时间短(并发)
吞吐量
复杂度简单中等复杂
适用场景低配机器批处理Web 服务

Serial 的典型使用场景

场景一:低配机器

bash
# 单核 CPU / 低内存机器
java -XX:+UseSerialGC -Xmx256m MyApp

场景二:容器环境(资源受限)

bash
# Kubernetes 中限制 256MB 内存
java -XX:+UseSerialGC -Xmx128m -Xms128m MyApp

场景三:短期程序

java
public class ShortLived {
    public static void main(String[] args) {
        // 程序只运行几秒
        // Serial 的停顿对总体时间影响不大
        process(args);
    }
}

Serial 的 GC 日志

bash
java -XX:+UseSerialGC \
     -XX:+PrintGCDetails \
     -XX:+PrintGCDateStamps \
     MyApp

日志示例:

# MinorGC(Serial 年轻代)
2026-03-22T10:00:00.123+0800: [GC (Allocation Failure)
  eden space 20480K, 90% used
  from space 2048K, 0% used
  to   space 2048K, 0% used
  : 18432K->2048K(22528K), 0.0156789 secs]
  [Times: user=0.01 sys=0.01, real=0.02 secs]

# FullGC(Serial Old 老年代)
2026-03-22T10:00:30.456+0800: [Full GC (Allocation Failure)
  [DefNew: 18432K->2048K(22528K)]
  [Tenured: 102400K->102400K(204800K), 1.2345678 secs]
  [Times: user=1.23 sys=0.00, real=1.23 secs]

Serial Old 的作用

Serial Old 不只是 Serial 的老年代版本,它还有一个重要角色:CMS 的备选方案(MSC - Mark Sweep Compact)

CMS 的备选流程:
CMS 执行中...

    │ 老年代空间不足以容纳新晋升对象


Serial Old 开始执行(MSC)

    │ Full GC + 压缩
    │ 停顿时间可能很长(CMS 失败的代价)


GC 完成,CMS 继续...

本节小结

Serial 收集器的核心要点:

维度SerialSerial Old
管理区域年轻代老年代
算法复制标记-压缩
线程数单线程单线程
STW是(年轻代停顿)是(老年代停顿)
适用场景低配机器、短期程序CMS 备选

Serial 是所有现代 GC 收集器的「老祖宗」。虽然现在很少在服务器上使用,但它简单可靠的特性,使其在低配和资源受限环境中仍有价值。

下一节,我们来看 ParNew 回收器

基于 VitePress 构建