何时选择SerialGC,ParallelGC而不是CMS,Java中的G1?

2022-09-01 06:54:06

在 Java 9 中,G1 GC 是缺省的垃圾回收器。截至目前,我听说有些人更喜欢CMS垃圾收集器而不是G1GC,因为它似乎不稳定并且有一些令人讨厌的错误。

ParallelGC发生了什么(这些天没有嗡嗡声)?是否有任何用例,我们希望更喜欢ParallelGC而不是CMS / G1?

此外,是否有任何情况下SerialGC可以执行所有这些并行收集器?


答案 1

串行收集器

主要用于单CPU机。

算法:

它使用单个线程来处理堆,并在任何 gc 期间执行停止世界暂停。只要把它看成玩具。

这是客户端类计算机(Windows 或单 CPU 计算机上的 32 位 jvm)的默认值。


并行收集器

算法:

它使用多个 gc 线程来处理堆,并在任何 gc 期间执行停止世界暂停。

<= Java ,这是服务器级机器(多CPU类unix机器或任何64位jvm)的默认设置。8


内容管理系统收集器

它旨在消除与并行和串行收集器的完整gc相关的长暂停。

算法:

它使用1个或多个gc线程定期扫描旧一代,并丢弃未使用的对象,暂停时间很短,但占用更多的CPU时间。

警告:自 Java 以来,它已被删除14


G1 收集器

它是低暂停/服务器样式gc,主要用于大型堆(>4Gb)。

算法:

  • 与CMS类似,它使用多个后台gc线程来扫描和清除堆。
  • 它将老一代分成几部分,它可以通过从1个部分复制到另一个部分来清理旧一代。
    因此,碎片化的可能性较小。

从Java开始,这是服务器级机器(多CPU类unix机器或任何64位jvm)的默认方法。9


为什么使用 G1 作为默认值?

主要原因是减少 gc 暂停时间,尽管整体吞吐量可能会降低。


答案 2

您可以阅读文档 Java 平台,标准版热点虚拟机垃圾回收调优指南-Java9

  • 串行收集器

    它最适合单处理器计算机,因为它不能利用多处理器硬件,尽管它在多处理器上对于具有小型数据集(最多约100 MB)的应用程序非常有用。

  • 并行收集器

    并行收集器也称为吞吐量收集器,它是类似于串行收集器的代收集器。串行收集器和并行收集器之间的主要区别在于并行收集器具有多个线程,用于加快垃圾回收速度。并行收集器适用于在多处理器或多线程硬件上运行的中型到大型数据集的应用程序。如果您不关心暂停时间而更喜欢吞吐量,则此收集器是最好的。

  • 大多数并发收集器(CMS)

此收集器在 Java9 中已弃用。

此收集器适用于喜欢较短的垃圾回收暂停时间并且能够负担得起与垃圾回收共享处理器资源的应用程序。

  • G1 垃圾回收器

    此服务器式收集器适用于具有大量内存的多处理器计算机。它以高概率满足垃圾回收暂停时间目标,同时实现高吞吐量。

总结:

  • 如果应用程序具有较小的数据集(最多约 100 MB),请使用选项 -XX:+UseSerialGC 选择串行收集器。

  • 如果应用程序将在单个处理器上运行,并且没有暂停时间要求,则使用选项 -XX:+UseSerialGC 选择串行收集器。

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

  • 如果响应时间比总体吞吐量更重要,并且垃圾回收暂停必须保持短于大约一秒,则选择具有 -XX:+UseG1GC 或 -XX:+UseConcMarkSweepGC 的并发收集器。

问与答:

  1. 我听说有些人更喜欢CMS垃圾收集器而不是G1GC,因为它似乎不稳定并且有一些令人讨厌的错误。

G1 收集器足够稳定,适用于大多数应用。我使用G1收集器进行许多应用程序,并且它们都运行良好。如果您可以将java9升级到Java11,那么它的工作效果更好,错误更少。

  1. 是否有任何用例,我们希望更喜欢ParallelGC而不是CMS / G1?

是的。一些需要更多吞吐量并且不关心使用并行收集器的暂停时间的应用程序会更好。例如,批处理任务,脱机作业,计算任务。

  1. 此外,是否有任何情况下SerialGC可以执行所有这些并行收集器?

如果您在嵌入式系统或具有一个或两个CPU的系统上运行JVM,则串行GC会更好。

最后,G1 VS CMS:在大多数情况下,G1可以取代CMS。在这种情况下,您最好使用G1:

  1. 你有一个很大的堆,比如16G。暂停时间和堆大小之间存在正相关关系。相反,G1 是增量收集器。
  2. 您有严格的暂停时间要求,并希望暂停时间更加可控。例如,您希望暂停时间< = 10ms。