📜  Java中 JVM 垃圾收集器的类型及其实现细节

📅  最后修改于: 2022-05-13 01:55:13.621000             🧑  作者: Mango

Java中 JVM 垃圾收集器的类型及其实现细节

先决条件:垃圾收集、标记和清除算法

垃圾收集:垃圾收集又名 GC 是Java最重要的特性之一。垃圾回收是Java中用于释放未使用内存的机制,它只是清除未使用对象占用的空间。为了释放未使用的内存,垃圾收集器跟踪所有仍在使用的对象,并将对象的其余部分标记为垃圾。基本上垃圾收集器使用标记和扫描算法来清除未使用的内存。

垃圾收集类型

JVM 实际上提供了四种不同的垃圾收集器。每个垃圾收集器的应用程序吞吐量和应用程序暂停都会有所不同。应用程序吞吐量表示Java应用程序运行的速度,应用程序暂停表示垃圾收集器清理未使用的内存空间所花费的时间。

  1. Serial Garbage Collector :这是最简单的 GC 实现,因为它基本上使用单线程。如果我们选择串行垃圾收集器作为我们的默认垃圾收集器,那么每当我们调用垃圾收集器来清理未使用的内存时,串行垃圾收集器就会保存应用程序的所有正在运行的线程,即它通过冻结所有应用程序线程来工作,它会创建一个线程来执行垃圾回收。它冻结所有其他正在运行的应用程序线程,直到垃圾收集操作结束。如果我们使用 Serial Garbage Collector 作为我们的默认垃圾收集器,那么应用程序吞吐量将会降低,应用程序暂停时间将会增加。结果,这个 GC 实现在运行时冻结了所有应用程序线程。因此,在服务器环境等多线程应用程序中使用它并不是一个好主意。

    执行:
    如果你想使用串行垃圾收集器,那么我们必须在运行 jar 时明确提及:

  2. Parallel Garbage Collector :Parallel Garbage Collector 是Java 8 中默认的垃圾收集器。它也被称为吞吐量收集器。 Parallel Garbage Collector 与 Serial Garbage Collector 相同,因为 Parallel Garbage Collector 在执行垃圾收集时也会冻结应用程序的运行线程。但不同的是,Parallel Garbage Collector 使用多个线程来执行未使用的堆区域的清理。使用垃圾收集器作为默认 GC 的优点是我们可以为垃圾收集器提及一些属性,例如
    • 垃圾收集器可以使用多少个线程来执行垃圾收集。

      执行:

    • 垃圾收集器在执行垃圾收集时可以采取的最大暂停时间

      执行:

    并行垃圾收集器比串行垃圾收集器好得多,但并行垃圾收集器的一个问题是它也会在次要操作期间暂停应用程序。最适合可以处理此类暂停的应用程序。如果我们使用 JDK 8,那么并行 GC 是默认的垃圾收集器。

    实现:如果我们在Java 9 上运行并且想要使用并行垃圾收集器,那么我们应该使用以下命令:

  3. CMS 垃圾收集器:CMS 垃圾收集器被称为并发标记清除垃圾收集器。该垃圾收集器使用多个线程一致地扫描堆内存以标记未使用的对象,然后扫描标记的对象。众所周知,串行垃圾收集器和并行垃圾收集器在执行垃圾收集时会冻结应用程序的运行线程。但是 CMS 垃圾收集器只会在两种情况下冻结正在运行的线程,即应用程序暂停:
    • 在执行垃圾回收时,如果并行堆内存发生变化。
    • 同时标记老年代空间中的引用对象。

    如果我们将 CMS 收集器与 Parallel 垃圾收集器进行比较,CMS 收集器使用更多的 CPU 来确保更好的应用程序吞吐量。如果我们正在开发一个可以提供更多 CPU 资源以获得更好性能的应用程序,那么 CMS 垃圾收集器是块引用而不是并行收集器的选择。要启用 CMS 垃圾收集器,我们可以使用以下参数:

  4. G1 垃圾收集器:首先在 JDK 7 中引入了 G1 垃圾收集器。最初,它旨在为更大的堆内存应用程序提供更好的支持。 G1 垃圾收集器是Java 9 的默认垃圾收集器。G1 收集器取代了 CMS 收集器,因为它更高效。 G1 垃圾收集器的工作方式与其他收集器不同。与其他收集器不同,G1 收集器将堆空间划分为多个大小相等的区域。基本上它主要是为堆大小大于 4GB 的应用程序设计的。它将堆区域划分为多个区域,从 1MB 到 32MB 不等。在执行垃圾收集时,G1 垃圾收集器标记堆区域,该区域具有在整个堆中使用的对象。通过这个垃圾收集器的帮助,可以获得关于包含最多使用较少对象的区域的信息,并且垃圾收集器首先仅在该区域上执行垃圾收集。这就是为什么它被称为 G first 垃圾收集器。 G1 还在垃圾收集之后压缩空闲堆空间,这使得 G1 垃圾收集器比其他垃圾收集器更好。 G1 Garbage Collector 是Java 9 的默认垃圾收集器。

    实现:如果我们使用低于 9 的Java版本并且我们想使用 G1 垃圾收集器,那么我们必须在运行 jar 文件时明确提及,例如: