收集器总览
收集器 | 所用算法 | 描述 | 触发STW机制 |
---|---|---|---|
Serial收集器 | 标记-压缩算法 | Serial收集器是JDK 1.3.1之前的默认垃圾收集器,它使用单线程进行垃圾收集工作。适用于在小型内存环境中使用。 | 它使用单线程进行垃圾收集,会导致应用程序暂停执行。 |
Parallel收集器 | 标记-压缩算法 | Parallel收集器在JDK 1.4版本中引入的,是Serial收集器的多线程版本,通过多个线程并行进行垃圾收集,提高垃圾收集的效率。适用于处理大量数据的应用。 | 使用多个线程进行垃圾收集。虽然其垃圾收集过程会导致短暂的STW暂停,但其并行的特性可以加快垃圾回收的速度。 |
CMS(Concurrent Mark Sweep)收集器 | 标记-清除算法 | CMS收集器在JDK 5中首次引入,是一种以获取最短回收停顿时间为目标的收集器。它通过多线程的方式,在垃圾收集的同时允许程序线程的并发执行。适用于对响应时间有较高要求的应用。 | 它的特点是在垃圾回收过程中,应用程序可以与垃圾收集器并发进行。但是,在初始标记和最终标记阶段,仍然需要触发STW机制。 |
G1(Garbage-First)收集器 | 标记-整理算法 | G1收集器在JDK 9中首次引入,是一种面向服务器端应用的垃圾收集器。它采用分区算法,将堆内存划分为多个区域,可以并行或并发地进行垃圾收集操作。它的特点是具有可预测的停顿时间和高效的内存回收。 | 它的特点是可以预测和控制垃圾回收的时间,并尽可能减少STW暂停的时间和频率。但是,在进行全局并发标记和整理阶段时,仍然需要触发STW机制。 |
ZGC(Z Garbage Collector) | 分代并发标记压缩算法 | ZGC在JDK 11中首次引入,是一种低停顿时间的垃圾收集器,适用于大内存场景下的应用。它通过将垃圾收集与应用线程并发执行,实现了很短的停顿时间。 | 几乎不触发STW机制。但是需要更大的堆空间来支撑。 |
Full GC
Full GC是指对整个Java堆进行垃圾回收的过程。在Full GC中,会对年轻代和老年代都进行GC操作,而不仅仅是年轻代。Full GC的目的是尽可能地回收内存空间,减少内存碎片和提高内存使用效率。Full GC通常会导致较长时间的停顿,因为会触发STW(Stop-the-World)机制,即在GC进行时,应用程序的运行会被暂停。Full GC一般发生在以下几种情况下:
- 老年代的使用率达到阈值(如CMS收集器的CMSInitiatingOccupancyFraction参数)。
- 执行了System.gc()方法。
- 出现分配失败(Allocation Failure)。
- 程序在某个时间点达到了最大堆内存限制。 Full GC的频率和耗时都较大,应尽量避免频繁的Full GC,这也是JVM调优的一个重要目标之一。
STW(Stop-the-World)机制是指在进行垃圾收集时,暂停所有应用线程的一种机制。它的的目的是确保垃圾收集器可以安全地操作对象,并且不会因为对象的变化而导致错误的回收或引用。为了确保对象的一致性,会先暂停所有应用线程,然后进行垃圾收集操作。
在STW期间,所有应用线程都会被暂停,不会继续执行任何任务。这意味着应用程序在此期间无法响应用户请求或执行任何操作,对于对实时性要求较高的应用来说可能会造成用户体验的下降。
STW暂停时间是垃圾收集器性能的重要指标之一。较短的STW暂停时间能够减少应用程序的响应时间,提升用户体验。
CMS收集器
CMS(Concurrent Mark Sweep)收集器是一种以获取最短回收停顿时间为目标的垃圾回收器。其主要流程如下:
- 初始标记(Initial Mark):在这个阶段,CMS收集器会暂停整个应用程序,触发STW机制。标记所有根对象,并标记要回收的对象,但只标记到一个停顿点。
- 并发标记(Concurrent Mark):在这个阶段,应用程序可以继续运行,CMS收集器会并发地遍历整个堆,并标记所有的存活对象。
- 重新标记(Remark):在这个阶段,CMS收集器会暂停整个应用程序,触发STW机制。以修补在并发标记阶段可能被修改的对象标记,并标记新的要回收的对象。
- 并发清除(Concurrent Sweep):在这个阶段,应用程序可以继续运行,CMS收集器会并发地清理并回收未被标记的对象。
- 并发重置(Concurrent Reset):在这个阶段,CMS收集器会完成内部数据结构的重置,为下一次垃圾回收做准备。
使用CMS收集器的优点是最短回收停顿时间,缺点是在标记和清理阶段对CPU资源的使用较多,可能会影响应用程序的吞吐量。
G1收集器
G1(Garbage-First)收集器是一种服务器端垃圾收集器,使用了分代收集的思想,同时也是JDK 9及之后版本中的默认垃圾收集器。 G1收集器的执行过程主要包括以下步骤:
- 初始标记:暂停所有应用线程,触发STW机制。标记所有的根对象(如静态变量、GC Root等),并标记与根对象直接可达的对象,完成后继续执行应用程序。
- 并发标记:在应用程序运行的同时,G1收集器会在后台运行并发标记阶段,标记所有的存活对象,包括通过初始标记后续创建的对象。这个过程是与应用程序并行执行的,所以不会停顿应用程序的执行。
- 最终标记:暂停所有应用线程,触发STW机制。完成并发标记阶段之后,G1收集器会再次标记所有的存活对象,确认标记阶段结束后的存活对象。
- 筛选回收:根据区域内存占用、垃圾对象比例等因素,确定每个区域是否需要回收。如果一个区域被标记为需要回收,G1收集器会将其中的存活对象拷贝到其他区域,然后将整个区域清空,以便下次分配新的对象。
- 整理空闲:G1收集器会对清空的区域进行空闲内存的整理,以提供连续的内存空间供后续的对象分配使用。
- 并发清除:在应用程序运行时,G1收集器会在后台运行并发清除阶段,回收被标记为垃圾的对象,并释放相应的内存空间。 G1收集器具有自适应的能力,会根据应用程序的运行情况,动态调整各个阶段的执行时间,从而更好地平衡吞吐量和停顿时间。此外,G1收集器还可以通过设置不同的参数来控制其行为,以满足不同应用场景的需求。
ZGC收集器
ZGC垃圾收集器在内存管理方面采用了Region的方式。它将整个堆内存划分为不同的Region,每个Region的大小通常为2MB。每个Region都有一个标记位,用于标记是否被使用。
ZGC的内存管理方式有以下特点:
- 并发标记:垃圾收集过程中,不会触发全局的STW(Stop-the-World)暂停,而是通过并发标记的方式,在应用程序运行的同时进行垃圾标记操作。
- 无需整理:ZGC不会像传统的垃圾收集器那样进行内存整理,而是通过复制和清除的方式来回收内存。当一个Region中的对象被标记为垃圾时,会将其复制到新的Region中,并将原Region标记为空闲状态,以便下次分配新的对象使用。
- 动态调整:ZGC可以动态调整Region的数量,以适应实时应用程序的内存需求。它可以根据应用程序的工作负载情况动态增加或减少Region的数量,以提供更好的性能和内存利用率。
通过以上的内存管理方式,ZGC能够在保证低延迟的同时,有效地管理堆内存,提供高性能的垃圾收集能力。
网友评论