Java面试题 - Java中常见的垃圾收集器有哪些?
引言
垃圾收集器(Garbage Collector, GC)是Java虚拟机(JVM)的重要组成部分,负责自动管理内存,回收不再使用的对象占用的内存空间。本文将介绍Java中常见的垃圾收集器及其工作原理,并通过流程图帮助理解。
1. 垃圾收集器概述
Java中的垃圾收集器主要分为以下几类:
- 串行收集器(Serial Collector)
- 并行收集器(Parallel Collector)
- 并发标记清除收集器(CMS Collector)
- G1收集器(Garbage-First Collector)
- ZGC (Z Garbage Collector)
- Shenandoah
2. 常见垃圾收集器详解
2.1 串行收集器(Serial Collector)
串行收集器是最基本的垃圾收集器,使用单线程进行垃圾回收工作,适合单CPU环境或小型应用。
特点:
- 单线程工作
- 回收时会暂停所有应用线程(Stop The World)
- 适用于客户端模式或小型应用
- 使用
-XX:+UseSerialGC
启用
2.2 并行收集器(Parallel Collector/Throughput Collector)
并行收集器使用多线程进行垃圾回收,适合多CPU环境,追求高吞吐量。
特点:
- 多线程并行回收
- 回收时仍会暂停所有应用线程
- 适合后台运算、批处理等注重吞吐量的应用
- 使用
-XX:+UseParallelGC
或-XX:+UseParallelOldGC
启用
2.3 并发标记清除收集器(CMS Collector)
CMS(Concurrent Mark-Sweep)收集器是一种以获取最短回收停顿时间为目标的收集器。
特点:
- 并发标记和清除,减少停顿时间
- 对CPU资源敏感
- 会产生内存碎片
- 在JDK9中被标记为废弃,JDK14中移除
- 使用
-XX:+UseConcMarkSweepGC
启用
2.4 G1收集器(Garbage-First Collector)
G1(Garbage-First)是从JDK7开始引入的服务器端垃圾收集器,目标是替代CMS。
特点:
- 分Region的内存布局
- 可预测的停顿时间模型
- 并行与并发结合
- 整体基于标记-整理,局部基于复制算法
- JDK9及以后版本的默认收集器
- 使用
-XX:+UseG1GC
启用
2.5 ZGC (Z Garbage Collector)
ZGC是JDK11中引入的低延迟垃圾收集器,目标是将停顿时间控制在10ms以内。
特点:
- 停顿时间不随堆大小增长而增长
- 处理TB级堆内存
- 基于Region内存布局
- 使用染色指针和内存屏障技术
- 使用
-XX:+UseZGC
启用
2.6 Shenandoah
Shenandoah是由Red Hat开发的一款低停顿时间垃圾收集器。
特点:
- 与ZGC类似,但实现方式不同
- 通过Brooks指针实现并发压缩
- 停顿时间与堆大小无关
- 使用
-XX:+UseShenandoahGC
启用
3. 垃圾收集器比较
收集器 | 算法 | 线程 | 适用场景 | 停顿时间 | 吞吐量 |
---|---|---|---|---|---|
Serial | 复制/标记-整理 | 单线程 | 客户端模式 | 长 | 一般 |
Parallel | 复制/标记-整理 | 多线程 | 后台运算 | 长 | 高 |
CMS | 标记-清除 | 多线程 | Web应用 | 短 | 一般 |
G1 | 标记-整理+复制 | 多线程 | 服务端 | 可预测 | 高 |
ZGC | 染色指针 | 多线程 | 大内存低延迟 | 极短 | 高 |
Shenandoah | Brooks指针 | 多线程 | 大内存低延迟 | 极短 | 高 |
4. 如何选择垃圾收集器
选择垃圾收集器时需要考虑以下因素:
- 应用需求:是追求高吞吐量还是低延迟?
- 堆大小:小堆还是大堆?
- CPU资源:单核还是多核?
- JDK版本:不同版本支持的收集器不同
一般建议:
- 客户端或小型应用:Serial
- 后台处理、批处理:Parallel
- Web应用:G1
- 大内存低延迟:ZGC或Shenandoah
5. 总结
Java提供了多种垃圾收集器以适应不同的应用场景,从单线程的Serial到低延迟的ZGC和Shenandoah,开发者可以根据应用需求选择合适的收集器。随着Java的发展,垃圾收集技术也在不断进步,未来可能会出现更高效的收集器。
理解各种垃圾收集器的工作原理和特点,有助于我们在实际开发中做出合理的选择和调优,从而提升应用性能。