Gc类型
在Java虚拟机(JVM)中,堆内存被划分为不同的区域,以便更有效地管理对象生命周期。最常见的分代垃圾回收策略将堆分为新生代(Young Generation)和老年代(Old Generation)。
- 新生代(Young Generation): 这是大多数新对象被创建的地方。新生代内部又分为一个伊甸园区(Eden Space)和两个幸存区(Survivor Spaces, 通常称为S0和S1)。
- 老年代(Old Generation / Tenured Generation): 用于存放生命周期较长的对象,这些对象在多次新生代垃圾回收后仍然存活。
1. Minor GC (年轻代GC)
Minor GC是发生在新生代的垃圾回收。
- 触发时机: 当伊甸园区被占满,新的对象无法分配空间时,就会触发Minor GC。
- 工作流程:
- 标记伊甸园区和其中一个幸存区(假设为S0)中所有存活的对象。
- 将这些存活的对象复制到另一个空的幸存区(S1)。
- 清空伊甸园区和S0区。
- 对象的年龄会增加,当对象的年龄达到一定阈值后,它将被提升到老年代。
- 特点: Minor GC非常频繁,执行速度快,并且通常会引发“Stop-the-World”暂停,即暂停所有应用线程。但由于新生代通常较小且大部分对象生命周期很短,所以这个暂停时间非常短暂。
2. Major GC (老年代GC)
Major GC是针对老年代的垃圾回收。
- 触发时机: 当老年代空间不足时,会触发Major GC。很多时候,Major GC是由Minor GC触发的,例如在Minor GC后,存活的对象需要晋升到老年代,而老年代空间不足以容纳它们。
- 工作流程: Major GC通常会检查老年代中所有对象,并回收不再使用的对象。
- 特点: Major GC的执行频率远低于Minor GC。由于老年代存放的对象更多且更复杂,Major GC的执行时间通常比Minor GC长得多,并且也会导致“Stop-the-World”,可能对应用响应造成更明显的影响。
3. Full GC (完全GC)
Full GC是对整个Java堆进行垃圾回收,包括新生代和老年代,有时也可能包括元空间(Metaspace)。
- 触发时机:
- 当老年代空间不足时。
- 当元空间(在Java 8之前是永久代)空间不足时。
- 当开发者显式调用
System.gc()时(虽然不推荐这样做,因为JVM有自己的判断机制)。
- 工作流程: Full GC会清理整个堆内存,回收所有不再存活的对象。
- 特点: Full GC是开销最大的一种垃圾回收,因为它需要处理整个堆,导致的应用暂停时间最长,应该尽量避免频繁发生。
重要说明: 对于Major GC和Full GC的定义,有时会存在一些混淆。在很多情况下,人们会将发生在老年代的GC称为Major GC,而将清理整个堆的GC称为Full GC。 有时,Full GC被视为Major GC的一种,或者说JVM日志中报告的Full GC实际上是对老年代的回收。 关键在于理解它们所作用的内存区域和带来的性能影响。
其他类型的垃圾回收器
除了上述GC活动类型,JVM还提供了多种垃圾回收器的具体实现,它们采用不同的算法和策略来平衡吞吐量和暂停时间。
-
Serial GC (串行GC):
- 这是最简单的垃圾回收器,使用单个线程执行所有GC任务。
- 当进行垃圾回收时,它会暂停所有应用线程(Stop-the-World)。
- 适用于内存较小、CPU核心数较少的单处理器环境,或者对暂停时间不敏感的小型应用。
- 可以通过
-XX:+UseSerialGC启用。
-
Parallel GC (并行GC):
- 也称为“吞吐量收集器”,是Java 8的默认垃圾回收器。
- 它使用多个线程并行地执行新生代垃圾回收,从而减少GC时间。
- 老年代的GC在早期版本中是单线程的,但后续也可以配置为多线程。
- 它的目标是最大化应用的吞吐量,适合于后台计算等对高吞吐量有要求但能容忍一定暂停时间的场景。
- 可以通过
-XX:+UseParallelGC启用。
-
Concurrent Mark Sweep (CMS) GC (并发标记清除GC):
- 该回收器的主要目标是最小化应用的暂停时间。
- 它在垃圾回收的大部分阶段(如标记和清除)都允许应用线程并发执行。
- 只在初始标记和重新标记这两个短暂阶段需要“Stop-the-World”。
- 适用于对响应时间有较高要求的中到大型应用。不过,它在JDK 9中被标记为废弃。
-
G1 GC (Garbage-First GC):
- 为替代CMS而生,适用于多处理器和大内存的服务器。
- 它将堆划分为多个大小相等的区域(Region),并优先回收垃圾最多的区域,这也是其名称“Garbage-First”的由来。
- G1是一个并发、并行的回收器,并且包含了增量压缩,可以有效避免内存碎片问题。
- 旨在实现可预测的低暂停时间。
-
ZGC (Z Garbage Collector):
- 从Java 11开始引入,作为一种可扩展的低延迟垃圾回收器。
- 它的设计目标是将GC暂停时间控制在10毫秒以内,无论堆大小如何。
- 通过使用有色指针和加载屏障等技术,实现了几乎所有工作都并发执行,极大地减少了“Stop-the-World”的时间。
- 非常适合需要极低延迟和使用大堆内存的应用。
-
Shenandoah GC:
- 在JDK 12中引入,与ZGC类似,也是一种以降低GC暂停时间为主要目标的并发垃圾回收器。
- 它通过与应用线程并发执行大部分GC工作(包括对象整理),来显著减少暂停时间。
-
Epsilon GC:
- 这是一个“无操作”(no-op)的垃圾回收器,只进行内存分配,但不回收任何内存。
- 它主要用于性能测试和分析,以衡量应用在没有GC干扰下的性能基线。