23. Java 中常见的垃圾收集器有哪些?
Java中常见的垃圾收集器(Garbage Collectors)主要包括以下几种,每种收集器在性能、停顿时间和适用场景方面各有特点。以下是几种主要的垃圾收集器及其特点:
1. Serial 收集器
工作原理:Serial收集器是一个单线程垃圾收集器,在进行垃圾收集时,会暂停所有应用程序线程(“Stop-the-World”),然后单线程地执行垃圾回收。
特点:
- 适用于单核或较小内存的环境。
- 由于是单线程操作,内存回收时会引发较长的停顿时间(尤其是堆内存较大时)。
- 是JVM客户端模式下的默认收集器。
适用场景:适合简单的、低负载的应用程序,例如客户端应用或开发测试环境。
参数:
-XX:+UseSerialGC
2. Parallel 收集器(Parallel GC 或者 Throughput Collector)
工作原理:Parallel收集器是多线程垃圾收集器,通过多线程并行地进行垃圾回收操作,旨在提高吞吐量(即尽可能减少GC停顿时间占总运行时间的比例)。
特点:
- 适用于多核处理器和大内存环境。
- 采用并行的方式进行垃圾回收,减少了GC引起的应用停顿时间。
- 可以配合自适应调优(通过设置目标暂停时间和吞吐量目标),JVM会自动调整堆大小和其他参数。
适用场景:适合需要高吞吐量的服务器端应用,如后台任务处理、大型批处理任务等。
参数:
-XX:+UseParallelGC
3. Parallel Old 收集器
工作原理:Parallel Old收集器是Parallel收集器的老年代版本,采用标记-整理算法进行垃圾回收,也支持多线程并行操作。
特点:
- 与Parallel收集器结合使用时,整个堆内存的回收都可以并行执行,进一步提升了吞吐量。
- 减少了在大内存应用中因GC引起的长时间停顿。
适用场景:适合大型企业级应用,需要在高吞吐量和相对较短的停顿时间之间找到平衡。
参数:
-XX:+UseParallelOldGC
4. CMS 收集器(Concurrent Mark-Sweep)
工作原理:CMS收集器以最小化应用停顿时间为目标,采用并发标记-清除算法。其标记阶段和应用程序线程并发执行,清除阶段进行内存回收时,部分线程也与应用并发运行。
特点:
- 减少了长时间的GC停顿,适合对响应时间要求高的应用。
- 由于是并发执行的,GC过程中CPU开销相对较大,可能会影响应用程序的性能。
- 容易产生内存碎片,可能导致“Concurrent Mode Failure”(并发模式失败),从而触发“Stop-the-World”事件进行Full GC。
适用场景:适合对低停顿时间有较高要求的应用,如交互式应用程序或互联网应用的后台服务。
参数:
-XX:+UseConcMarkSweepGC
5. G1 收集器(Garbage First)
工作原理:G1收集器是JDK 7引入的面向服务端应用的垃圾收集器。G1将堆内存分成多个大小相等的区域(Region),通过并行和并发方式来回收内存,并根据垃圾回收收益优先处理最多的垃圾区域(因此称为“Garbage First”)。
特点:
- 通过分代收集和区域回收相结合,减少了Full GC的频率,并且在大内存环境中表现优越。
- 能够在一定程度上控制停顿时间,通过设置目标暂停时间,G1尝试在预定的时间内完成垃圾回收。
- 适合大内存、多核处理器的环境,具备良好的性能和较短的停顿时间。
适用场景:适合大内存、多核服务器,尤其是那些希望在合理停顿时间内平衡垃圾回收和应用性能的应用程序。
参数:
-XX:+UseG1GC
6. ZGC 收集器(Z Garbage Collector)
工作原理:ZGC是JDK 11引入的一种超低停顿时间的垃圾收集器,旨在使GC停顿时间不超过10毫秒,即使在数百GB或TB级别的堆内存中。它采用了基于颜色的指针和并发标记-复制算法。
特点:
- 具有极低的停顿时间(一般在10毫秒以内),即使在极大的堆内存中也能维持这一目标。
- 在后台进行大多数的垃圾收集工作,减少了“Stop-the-World”的频率。
- 适用于超大规模内存应用。
适用场景:适合需要处理非常大内存的高性能、低延迟应用,如金融应用、大数据处理系统等。
参数:
-XX:+UseZGC
7. Shenandoah 收集器
工作原理:Shenandoah是由Red Hat开发的一种低停顿时间的垃圾收集器,类似于ZGC,但采用不同的技术实现。Shenandoah通过并发压缩和标记-清除算法实现低停顿时间。
特点:
- 通过并发回收和压缩,尽可能减少停顿时间。
- 适用于大内存、低停顿时间的应用场景。
适用场景:适用于对停顿时间极度敏感的大型应用,特别是在多线程、多核环境下。
参数:
-XX:+UseShenandoahGC
总结
Java中的垃圾收集器种类繁多,适用于不同的应用场景和性能要求。选择合适的垃圾收集器需要根据具体的应用特点、性能需求(如吞吐量、延迟)以及硬件环境来做出决定。常见的收集器包括Serial GC
、Parallel GC
、CMS
、G1 GC
,以及在JDK 11及之后引入的ZGC
和Shenandoah GC
,它们分别适用于不同规模和类型的应用程序。