Parallel Scavenge (PS) 垃圾收集器

124 阅读2分钟

Parallel Scavenge (PS) 垃圾收集器

Parallel Scavenge(PS)收集器是 JVM 中专注于高吞吐量的垃圾收集器,特别适合后台运算型应用。ps与parnew使用相同的垃圾回收方式,使用相同的卡变,唯一不同的是ps关注吞吐量,以吞吐量为维度建立垃圾收集模型。以下是全面剖析:

graph TD
    A[Parallel Scavenge] --> B[设计目标]
    A --> C[工作模式]
    A --> D[内存管理]
    A --> E[调优策略]
    A --> F[适用场景]

    B --> B1[最大化吞吐量]
    B --> B2[减少GC总时间]
    B --> B3[可预测停顿]

    C --> C1[多线程并行]
    C --> C2[分代收集]
    C --> C3[自适应调节]

    D --> D1[复制算法]
    D --> D2[标记-整理]
    D --> D3[卡表技术]

    E --> E1[吞吐量优先]
    E --> E2[暂停时间控制]

    F --> F1[计算密集型]
    F --> F2[批处理系统]

一、核心设计哲学

1. 吞吐量优先模型

graph LR
    目标[高吞吐量] --> 策略[减少GC时间占比]
    策略 --> 公式["吞吐量 = 1 - (GC时间 / 总运行时间)"]

    实现 --> 并行[多线程并行收集]
    实现 --> 自适应[自适应调节]

2. 与 CMS/G1 的目标对比

pie
    title 设计目标对比
    "PS:吞吐量" : 70
    "CMS:低暂停" : 60
    "G1:平衡" : 50
    "ZGC:亚毫秒暂停" : 30

二、工作模式详解

1. 年轻代收集(Parallel Scavenge)

sequenceDiagram
    应用线程->>JVM: 对象分配
    JVM->>PS: Eden空间不足
    PS->>所有线程: STW暂停
    loop 多线程并行
        PS->>PS: 标记存活对象
        PS->>PS: 复制到Survivor区
    end
    PS->>所有线程: 恢复运行

2. 老年代收集(Parallel Old)

flowchart TD
    触发[老年代空间不足] --> STW[完全暂停]
    STW --> 标记[并发标记]
    标记 --> 整理[滑动整理]
    整理 --> 清除[清除垃圾]
    清除 --> 恢复[恢复运行]

三、内存管理机制

1. 分代结构

graph TD
    Heap[堆内存] --> Young[年轻代]
    Heap --> Old[老年代]

    Young --> Eden[Eden区]
    Young --> S0[Survivor0]
    Young --> S1[Survivor1]

    Old --> Tenured[连续空间]

2. 收集算法对比

区域算法特点
年轻代复制算法高效清除,无碎片
老年代标记-整理内存连续,避免碎片

四、自适应调节技术

1. 自动优化机制

graph TD
    监控[GC监控] --> 分析[性能分析]
    分析 --> 调节[参数动态调节]

    调节 --> 年轻代[调整年轻代大小]
    调节 --> 晋升[调整晋升阈值]
    调节 --> 线程[调整GC线程数]

2. 可调参数示例

classDiagram
    class PS参数 {
        -XX:MaxGCPauseMillis
        -XX:GCTimeRatio
        -XX:YoungGenerationSizeIncrement
        -XX:AdaptiveSizePolicyWeight
    }

五、关键配置参数

1. 基础启用参数

# 启用Parallel Scavenge
-XX:+UseParallelGC

# 启用Parallel Old
-XX:+UseParallelOldGC

2. 核心调优参数

参数默认值建议值作用
-XX:ParallelGCThreadsCPU核数=物理核数GC线程数
-XX:MaxGCPauseMillis无限制100-500最大暂停目标
-XX:GCTimeRatio9919-99GC时间占比
-XX:SurvivorRatio86-10Eden/Survivor比例
-XX:+UseAdaptiveSizePolicytrue保持开启自适应策略

六、最佳实践配置

1. 标准配置模板

# 8核服务器配置
java -XX:+UseParallelGC \
     -XX:+UseParallelOldGC \
     -XX:ParallelGCThreads=8 \
     -XX:MaxGCPauseMillis=200 \
     -XX:GCTimeRatio=19 \
     -Xmx8g -Xms8g \
     -jar batch-app.jar

2. 优化方向

mindmap
  root((优化方向))
    提高吞吐量
      增大堆内存
      增加GC线程
    控制暂停
      设置MaxGCPauseMillis
      减小年轻代
    避免Full GC
      增大老年代
      优化对象分配

七、与其它收集器对比

1. 吞吐量收集器对比

特性Parallel ScavengeG1ZGC
目标最大吞吐量平衡最低暂停
暂停时间中等可控亚毫秒
堆大小<64GB<100GB4TB+
适用场景批处理通用低延迟

2. 选择决策树

graph TD
    需求{应用需求}
    需求 -->|高吞吐| PS[Parallel Scavenge]
    需求 -->|低延迟| G1[G1 GC]
    需求 -->|超大堆| ZGC[ZGC]

    PS --> 批处理[批处理/计算]
    G1 --> 通用[Web服务/中间件]
    ZGC --> 实时[金融交易/实时系统]

八、生产案例

1. 大数据处理优化

graph TD
    问题[Spark作业GC占30%] --> 分析[诊断工具]
    分析 --> 原因[年轻代过小]
    优化 --> 配置["-Xmn4g → -Xmn8g"]
    结果 --> 提升[GC占比降至10%]

2. 参数调整验证

# 调整前
jstat -gcutil 12345
  S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
  0.00   0.00  85.00  70.00  95.00  92.00    100    50.0     5     10.0    60.0

# 调整后(-XX:MaxGCPauseMillis=200)
  0.00   0.00  80.00  65.00  95.00  92.00    120    40.0     5     10.0    50.0

总结结论

  1. 核心价值

    • 吞吐量王者:在计算密集型场景提供最高吞吐
    • 自适应优化:自动调整参数减少人工调优
    • 大内存管理:高效处理数十GB堆内存
  2. 最佳实践

    journey
        title PS使用策略
        section 启用
          使用ParallelGC : 5: 必须
          配合ParallelOld : 5: 必须
        section 调优
          设置MaxGCPauseMillis : 4: 重要
          调整GCTimeRatio : 3: 推荐
        section 监控
          定期检查GC日志 : 5: 关键
    
  3. 现代演进

    • JDK 8u20+:增强自适应策略
    • JDK 11+:被G1取代为默认收集器
    • JDK 17+:仍作为高吞吐场景首选

​最终建议​​:

对于批处理、数据计算等吞吐敏感型应用,Parallel Scavenge 仍是 JDK 8-17 的最佳选择。配置核心参数:

-XX:+UseParallelGC
-XX:ParallelGCThreads=CPU核数
-XX:MaxGCPauseMillis=200
-XX:GCTimeRatio=19

新项目建议基于 JDK 17+ 使用 ZGC,在保证吞吐的同时获得更低延迟。