JVM垃圾收集器概述
JVM提供了多种垃圾收集器(GC),每种都有其特点和适用场景。以下是主流垃圾收集器的使用指南:
- 小型应用:Serial GC
- 吞吐量优先:Parallel GC
- 延迟敏感:G1 GC或ZGC/Shenandoah
- 超大堆:G1 GC(JDK8)或ZGC(JDK15+)
- 最新技术:ZGC或Shenandoah
注意:不同JDK版本支持的GC可能不同,建议根据具体JDK版本和应用程序特性选择合适的收集器。
1. Serial收集器
特点:
- 单线程收集器
- 适用于客户端模式
- 使用标记-复制算法(新生代)和标记-整理算法(老年代)
使用方式:
markdown
markdown
复制
-XX:+UseSerialGC
适用场景:
- 单核CPU环境
- 小型应用
- 客户端应用
2. Parallel/Throughput收集器
特点:
- 多线程并行收集
- 关注吞吐量
- 新生代使用标记-复制,老年代使用标记-整理
使用方式:
markdown
markdown
复制
-XX:+UseParallelGC
-XX:+UseParallelOldGC
适用场景:
- 多核服务器
- 注重吞吐量的应用
- 批处理任务
3. CMS(Concurrent Mark-Sweep)收集器
特点:
- 并发标记清除
- 低停顿时间
- 使用标记-清除算法
使用方式:
markdown
markdown
复制
-XX:+UseConcMarkSweepGC
适用场景:
- 重视响应时间的应用
- 中等规模堆内存(2-4GB)
- 老年代收集
4. G1(Garbage-First)收集器
特点:
- 分区域收集
- 可预测停顿时间
- 标记-整理算法
使用方式:
markdown
markdown
复制
-XX:+UseG1GC
适用场景:
- 大堆内存(6GB以上)
- 需要平衡吞吐量和延迟
- JDK9+默认收集器
5. ZGC收集器
特点:
- 超低延迟(10ms以下)
- 可扩展至TB级堆
- 并发收集
使用方式:
markdown
markdown
复制
-XX:+UseZGC
适用场景:
- 超大堆内存应用
- 对延迟极度敏感的应用
- JDK15+生产可用
6. Shenandoah收集器
特点:
- 低暂停时间
- 并发压缩
- 与ZGC类似但实现不同
使用方式:
-XX:+UseShenandoahGC
适用场景:
- 需要低延迟的应用
- OpenJDK发行版
常见的垃圾回收算法
JVM(Java Virtual Machine)中的垃圾回收(Garbage Collection, GC)是自动内存管理机制的一部分,主要用于回收不再使用的对象所占用的内存空间。常见的垃圾回收算法主要包括以下几种:
1. 标记-清除算法(Mark-Sweep)
- 原理:
-
- 标记阶段:从根节点开始遍历对象图,标记所有可达的对象为存活对象。
- 清除阶段:遍历整个堆,将未被标记的对象回收。
- 优点:实现简单。
- 缺点:
-
- 会产生内存碎片,可能导致分配大对象时无法找到连续的空间。
- 清除过程中需要暂停应用线程(Stop-The-World)。
2. 复制算法(Copying)
- 原理:
-
- 将内存划分为两个相等的区域(From 和 To)。
- 每次只使用其中一个区域(From),当该区域满时,将存活的对象复制到另一个区域(To),然后清空原区域。
- 优点:
-
- 解决了内存碎片问题。
- 实现高效,适合年轻代(Young Generation)中大量短命对象的回收。
- 缺点:
-
- 内存利用率较低,因为只能使用一半的内存空间。
3. 标记-整理算法(Mark-Compact)
- 原理:
-
- 标记阶段:与标记-清除算法相同,标记所有存活对象。
- 整理阶段:将所有存活对象向一端移动,然后清理掉边界外的内存。
- 优点:
-
- 避免了内存碎片问题。
- 提高了内存利用率。
- 缺点:
-
- 整理阶段增加了额外的开销。
4. 分代收集算法(Generational Collection)
- 原理:
-
- 将堆内存划分为不同的代(Generation),通常分为年轻代(Young Generation)和老年代(Old Generation)。
- 年轻代使用复制算法,主要处理短命对象。
- 老年代使用标记-清除或标记-整理算法,处理长命对象。
- 优点:
-
- 根据对象生命周期的不同特点选择合适的算法,提高了GC效率。
- 减少了全局GC的频率。
- 常见实现:
-
- Serial GC:单线程GC,适用于小型应用。
- Parallel Scavenge GC:多线程GC,适用于吞吐量优先的应用。
- CMS(Concurrent Mark Sweep) GC:以最短停顿时间为目标的GC,适用于响应时间敏感的应用。
- G1(Garbage First) GC:将堆划分为多个大小相等的Region,优先回收垃圾最多的Region,适用于大堆内存应用。
5. 增量收集算法(Incremental Collection)
- 原理:
-
- 将一次完整的GC过程分成多个小步骤,交替执行GC和应用程序线程,减少单次停顿时间。
- 优点:
-
- 降低了长时间停顿对应用的影响。
- 缺点:
-
- 实现复杂度较高,且可能引入额外的性能开销。
6. 分区收集算法(Region-based Collection)
- 原理:
-
- 将堆内存划分为多个独立的Region(如G1 GC中的Region),每个Region可以独立进行GC。
- 优点:
-
- 可以灵活控制GC的粒度,减少全局GC的频率。
- 支持并行和并发GC操作,提升性能。
- 典型实现:
-
- G1 GC 是分区收集算法的典型代表。
总结
| 算法名称 | 适用场景 | 主要优点 | 主要缺点 |
|---|---|---|---|
| 标记-清除 | 老年代 | 简单易实现 | 内存碎片化 |
| 复制 | 年轻代 | 无内存碎片 | 内存利用率低 |
| 标记-整理 | 老年代 | 无内存碎片,内存利用率高 | 整理阶段开销大 |
| 分代收集 | 通用场景 | 提高GC效率 | 实现复杂 |
| 增量收集 | 对响应时间敏感的应用 | 减少单次停顿时间 | 实现复杂,性能开销大 |
| 分区收集 | 大堆内存应用 | 灵活控制GC粒度,减少全局GC | 实现复杂 |
在实际应用中,JVM会根据堆的大小、对象生命周期的特点以及应用的需求选择合适的垃圾回收算法。例如,G1 GC结合了分代收集和分区收集的优点,适用于大堆内存和低延迟要求的应用场景。