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:ParallelGCThreads | CPU核数 | =物理核数 | GC线程数 |
-XX:MaxGCPauseMillis | 无限制 | 100-500 | 最大暂停目标 |
-XX:GCTimeRatio | 99 | 19-99 | GC时间占比 |
-XX:SurvivorRatio | 8 | 6-10 | Eden/Survivor比例 |
-XX:+UseAdaptiveSizePolicy | true | 保持开启 | 自适应策略 |
六、最佳实践配置
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 Scavenge | G1 | ZGC |
|---|---|---|---|
| 目标 | 最大吞吐量 | 平衡 | 最低暂停 |
| 暂停时间 | 中等 | 可控 | 亚毫秒 |
| 堆大小 | <64GB | <100GB | 4TB+ |
| 适用场景 | 批处理 | 通用 | 低延迟 |
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
总结结论
-
核心价值:
- 吞吐量王者:在计算密集型场景提供最高吞吐
- 自适应优化:自动调整参数减少人工调优
- 大内存管理:高效处理数十GB堆内存
-
最佳实践:
journey title PS使用策略 section 启用 使用ParallelGC : 5: 必须 配合ParallelOld : 5: 必须 section 调优 设置MaxGCPauseMillis : 4: 重要 调整GCTimeRatio : 3: 推荐 section 监控 定期检查GC日志 : 5: 关键 -
现代演进:
- 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,在保证吞吐的同时获得更低延迟。