串行收集器

串行收集器使用单个线程来执行所有垃圾收集工作,这使得它相对高效,因为线程之间没有通信开销。它最适合单处理器机器,因为它不能利用多处理器硬件,尽管它对于具有小数据集(最多约 100 MB)的应用程序在多处理器上很有用。在某些硬件和操作系统配置上默认选择串行收集器,或者可以使用选项显式启用-XX:+UseSerialGC。

并行收集器

并行收集器也称为吞吐量收集器,它是类似于串行收集器的分代收集器。串行收集器和并行收集器之间的主要区别在于并行收集器具有多个线程,用于加速垃圾收集。并行收集器适用于在多处理器或多线程硬件上运行的具有中型到大型数据集的应用程序。您可以使用该-XX:+UseParallelGC选项启用它。并行压缩是使并行收集器能够并行执行 major 收集的特性。如果没有并行压缩,major收集是使用单个线程执行的,这会显着限制可伸缩性。如果指定了选项-XX:+UseParallelGC,则默认启用并行压缩。您可以使用该-XX:-UseParallelOldGC选项禁用它。

大多数并发收集器

Concurrent Mark Sweep (CMS) 收集器和 Garbage-First (G1) 垃圾收集器是两个主要并发的收集器。大多数并发收集器对应用程序执行一些昂贵的并发工作。

  • CMS 收集器:此收集器适用于喜欢较短的垃圾收集暂停并且能够与垃圾收集共享处理器资源的应用程序。使用该选项-XX:+UseConcMarkSweepGC启用 CMS 收集器。CMS 收集器从 JDK 9 开始被弃用。

  • G1 垃圾收集器:这种服务器式收集器适用于具有大量内存的多处理器机器。它大概率的既能满足垃圾收集暂停时间目标,同时实现高吞吐量。在某些硬件和操作系统配置上默认选择 G1,或者可以使用-XX:+UseG1GC.

如何选择收集器

除非您的应用程序有相当严格的暂停时间要求,否则首先运行您的应用程序并允许 VM 选择一个收集器。

如有必要,调整堆大小以提高性能。如果性能仍然不能满足您的目标,则使用以下指南作为选择收集器的起点

  • 如果应用程序的数据集很小(最多大约 100 MB),则选择带有选项的串行收集器-XX:+UseSerialGC。
  • 如果应用程序将在单个处理器上运行并且没有暂停时间要求,则选择带有选项的串行收集器-XX:+UseSerialGC。

  • 如果 (a) 峰值应用程序性能是第一优先级并且 (b) 没有暂停时间要求或可以接受一秒或更长的暂停,则让 VM 选择收集器或选择带有 的并行收集器-XX:+UseParallelGC。

  • 如果响应时间比总吞吐量更重要,并且垃圾收集暂停必须保持在大约一秒以内,则选择带有-XX:+UseG1GC的G1收集器或-XX:+UseConcMarkSweepGC的CMS收集器。

这些指南仅提供了选择收集器的起点,因为性能取决于堆的大小、应用程序维护的实时数据量以及可用处理器的数量和速度。暂停时间对这些因素特别敏感,因此前面提到的一秒阈值只是一个近似值。在许多堆大小和硬件组合上,并行收集器将遇到超过一秒的暂停时间。相反,在某些情况下,并发收集器可能无法保持短于一秒的暂停。如果推荐的收集器没有达到所需的性能,则首先尝试调整堆和生成大小以满足所需的目标。如果性能仍然不足,则尝试不同的收集器:使用并发收集器减少暂停时间,并使用并行收集器增加多处理器硬件上的总体吞吐量。