Types of Garbage Collector in Java

2025年5月2日 | 阅读 5 分钟

在 Java 中,垃圾回收是一种提供自动内存管理的机制。它由 JVM 完成。程序员无需处理对象的分配和释放。在前面的章节中,我们还讨论了垃圾回收的工作原理。

如果您还不熟悉垃圾回收,我们建议您首先了解垃圾回收、Java 堆内存管理。在本节中,我们将讨论Java 中垃圾回收的类型

垃圾回收器类型

Java 中有种垃圾回收器,可以根据需要使用。

  • 串行垃圾回收器
  • 并行垃圾回收器
  • 并发标记清除 (CMS) 垃圾回收器
  • 垃圾优先 (G1) 垃圾回收器

每种垃圾回收器的性能和工作方式完全不同。它们各有优缺点。Java 允许我们选择 JVM 使用的任何一种垃圾回收器。要选择 GC,我们需要传递 JVM 参数。选择适合应用程序的垃圾回收器很困难。让我们逐一讨论每种垃圾回收器。

Types of Garbage Collector in Java

串行垃圾回收器

串行垃圾回收器非常适合单线程环境。它只使用一个线程进行垃圾回收。它通过暂停应用程序的所有线程来工作。这意味着在垃圾回收过程中,应用程序的线程会由串行垃圾回收器冻结,这个过程称为Stop the World 事件。避免在服务器环境中使用串行 GC。我们可以将其用于简单程序。如果要使用串行垃圾回收器,请执行 -XX:+UseSerialGC JVM 参数来激活它。

Types of Garbage Collector in Java

并行垃圾回收器

并行垃圾回收器是 JVM 使用的默认 GC。并行垃圾回收器的工作方式与串行垃圾回收器相同。串行和并行垃圾回收器之间的唯一区别是,串行垃圾回收器在垃圾回收过程中使用一个线程,而并行垃圾回收器使用多个线程进行垃圾回收。Parallel GC 可以利用多个 CPU 来加快应用程序吞吐量。因此,它也被称为吞吐量收集器。如果我们要执行长时间运行的进程(例如批处理),并且可以接受长时间的暂停,则使用它。如果要使用并行垃圾回收器,请执行 -XX:+UseParallelGC JVM 参数来激活它。

Types of Garbage Collector in Java

我们还可以使用以下 JVM 参数来配置并行 GC:

JVM 参数描述
-XX:ParallelGCThreads=<n>它控制 GC 线程的数量 (n)。
-XX:MaxGCPauseMillis=<t>它指定最大暂停时间*。
-XX:GCTimeRatio=<n>它指定最大的吞吐量目标**。

*暂停时间:两次 GC 之间的时间间隔。

**吞吐量目标:垃圾回收期间花费的时间与非垃圾回收期间花费的时间之比称为吞吐量目标。

并发标记清除 (CMS) 垃圾回收器

CMS 使用多个线程扫描堆,并在扫描过程中标记要清除的实例,扫描完成后,清除标记的实例。它在垃圾回收期间不会暂停应用程序的线程。GC 线程与应用程序线程并发执行。因此,与其他 GC 相比,它使用更多的 CPU。它也被称为低暂停并发收集器。仅当满足以下两种情况时,它才会冻结应用程序的所有线程:

  • 在标记老年代区域中的引用对象时。
  • 如果在垃圾回收过程中并行地对堆内存进行了任何更改。

我们可以使用多个 CPU 来获得更好的应用程序吞吐量。如果有更多的 CPU 可用,我们应该使用 CMS 垃圾回收器。因此,它比并行垃圾回收器具有优势。如果要使用 CMS 垃圾回收器,请执行 -XX:+USeParNewGC JVM 参数来激活它。我们还可以使用 -XX:ParallelCMSThreads=<n> JVM 参数来设置 GC 线程的数量。

Types of Garbage Collector in Java

注意:JVM 参数 -XX:+UseConcMarkSweepGC 已被弃用,因为它在命令行请求时会发出警告消息。

垃圾优先 (G1) 垃圾回收器

当内存(堆空间)很大(超过 4GB)时,可以使用 G1 垃圾回收器。它将堆分成大小相等的块(通常为 1MB 到 32MB),对它们进行优先级排序,然后根据优先级对这些块执行并行垃圾回收。

Eden、Survivor 和 Old 区域使用这种大小相等的区域来分配对象内存。除了这些内存区域,G1 GC 中还有另外两种类型的区域:

  • Humongous:当对象尺寸很大时使用。
  • Available:表示未占用的空间。
Types of Garbage Collector in Java

G1 GC 显示一个并发全局标记阶段,以确定整个堆中的活动对象和死对象。标记阶段完成后,G1 收集包含最多垃圾对象的区域的信息。然后先清除这些区域。如果要使用 G1 垃圾回收器,请执行 -XX:+UseG1GC JVM 参数来激活它。

Stop the World 事件

这是一种情况,当垃圾回收器执行垃圾回收 (GC) 时,它会停止所有应用程序线程,直到 GC 过程完成。这个过程称为Stop the World (STW) 事件。

Java 8 以来垃圾回收器的改进

在 Java 8 中,G1 垃圾回收器得到了更新。更新后的 GC 提供了 -XX:+UseStringDeduplication JVM 参数,该参数可以优化堆内存。它将重复的 String 值删除到单个 char[] 数组。

垃圾回收 JVM 选项

Java 垃圾回收的关键选项如下:

JVM 参数

该表描述了可以用来指示 JVM 的参数。

选项描述
-XX:+UseSerialGC串行垃圾回收器
-XX:+UseParallelGC并行垃圾回收器
-XX:+UseConcMarkSweepGCCMS 垃圾回收器
-XX:ParallelCMSThreads=CMS 收集器 - 要使用的线程数
-XX:+UseG1GCG1 垃圾回收器
其他重要参数
-XX:InitiatingHeapOccupancyPercent=<n>它控制启动并发周期后的堆占用率。这里,n 是堆空间的百分比。默认百分比为45
-XX:G1MixedGCLiveThresholdPercent=<t>如果 OLD 区域中的活动对象存在的值大于或等于此选项,则将其从 GC 对象中排除。这里,t 是以毫秒为单位的时间。默认值为65
-XX:G1HeapWastePercent=<r>它指定允许浪费的区域数量。这里,r 是区域的数量。默认值为10

GC 优化选项

选项描述
-Xms它指定初始堆大小。
-Xmx它最大化堆大小。
-Xmn用于指定 Young Generation 的大小。
-XX:PermSize初始永久代大小
-XX:MaxPermSize用于指定永久代 (PermGen) 的最大大小。

JVM GC 选项的用法

我们已经讨论了所有四种类型的 Java 垃圾回收器。但是选择一个很难,因为它取决于应用程序场景、硬件可用性和吞吐量要求。