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



在Java 9中,G1 GC是默认的垃圾收集器。到目前为止,我听说有些人更喜欢CMS垃圾收集器而不是G1GC,因为它似乎不稳定,并且有一些讨厌的bug。

ParallelGC发生了什么(最近没什么消息)?有没有什么用例我们更喜欢ParallelGC而不是CMS/G1?

此外,是否存在SerialGC可以执行所有这些并行收集器的情况?


串行采集器

主要用于单cpu机器。

算法:

它使用一个线程来处理堆,并在任何gc期间执行stop-the world暂停。把它当成玩具。

这是客户端类机器(windows或单cpu机器上的32位jvm)的默认设置。


并联集电极

算法:

它使用多个gc线程来处理堆,并在任何gc期间执行stop-the world暂停。

<=Java8,这是服务器类机器(多cpu类unix机器或任何64位jvm)的默认值。


CMS收集器

它旨在消除与parallel&串行收集器。

算法:

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

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


G1集电极

它是低暂停/服务器风格的gc,主要用于大堆(>4Gb)。

算法:

  • 类似于CMS,它使用多个后台gc线程来扫描&清除堆
  • 它将旧一代划分为多个部分,可以通过从一个部分复制到另一个部分来清理旧一代
    因此,获得碎片的可能性较小

由于Java9,这是服务器类机器(多cpu类unix机器或任何64位jvm)的默认设置。


为什么使用G1作为默认值

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

您可以阅读文档Java Platform,Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide-Java9

  • 串行收集器

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

  • 并行收集器

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

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

Java9中不赞成使用此收集器。

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

  • G1垃圾收集器

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

摘要:

  • 如果应用程序有一个小数据集(最大约100 MB),则选择带有选项-XX:+UseSerialGC的串行收集器。

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

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

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

Q&A:

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

G1收集器对于大多数应用来说足够稳定。我在许多应用程序中都使用了G1收集器,并且所有应用程序都运行良好。如果您可以将java9升级到Java11,它会更好地工作,错误也会更少。

  1. 有没有任何用例我们更喜欢ParallelGC而不是CMS/G1

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

  1. 此外,在任何情况下,SerialGC都可以执行所有这些并行收集器吗

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

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

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

使用串行:
-只有1CPU可用,没有暂停要求-单机上存在小型JVM(超过CPU数量)-小型实时数据集(小于100MB)

使用并行:
-非交互批处理应用程序,其中应用程序性能比低暂停时间更重要

最新更新