更新时间:2022-09-05 10:34:01 来源:极悦 浏览3207次
本文档将解释什么是 java 中的垃圾收集器以及主要的垃圾收集器类型以及每个垃圾收集器的行为。
Java 是一种面向对象的编程语言,包括Automatic Garbage Collection。Java 会自动分配和取消分配内存,因此程序不会承担该任务。现在(Java-12),Java 有七种类型的垃圾收集器。
这是最简单的 GC 实现。它基本上是为单线程环境设计的。此GC垃圾回收实现在运行时冻结所有应用程序线程。它使用单线程进行垃圾收集。因此,在服务器环境等多线程应用程序中使用它并不是一个好主意。
要启用串行垃圾收集器,我们可以使用以下参数:
java -XX:+UseSerialGC -jar Application.java
并行垃圾收集器也称为吞吐量收集器。与串行垃圾收集器不同,它使用多个线程进行垃圾收集。与串行垃圾收集器类似,这也会在执行垃圾收集时冻结所有应用程序线程。垃圾收集器最适合那些可以承受应用程序暂停的应用程序。
要启用并行垃圾收集器,我们可以使用以下参数:
java -XX:+UseParallelGC -jar Application.java
如果我们使用这个GC,我们可以指定最大垃圾收集线程和暂停时间、吞吐量和占用空间(堆大小)
可以使用命令行选项控制垃圾收集器线程的数量
-XX: ParallelGCThreads=<N>
使用命令行选项指定最大暂停时间目标(两次GC之间的间隔 [以毫秒为单位] )
-XX: MaxGCPauseMillis=<N>
最大吞吐量目标(根据执行垃圾收集所花费的时间与在垃圾收集之外花费的时间来衡量)由命令行选项指定
-XX:GCTimeRatio=<N>
使用选项-Xmx <N>指定最大堆占用空间(程序运行时所需的堆内存量)。
并发标记扫描 (CMS) 垃圾收集器使用多个垃圾收集器线程进行垃圾收集。它扫描堆内存以标记要驱逐的实例,然后扫描标记的实例。它专为喜欢更短的垃圾收集暂停的应用程序而设计,并且可以在应用程序运行时与垃圾收集器共享处理器资源。
CMS 垃圾收集器仅在以下两种情况下持有所有应用程序线程
在标记老年代空间中的引用对象期间。
堆内存的任何变化与垃圾回收并行
与并行垃圾收集器相比,CMS 收集器使用更多的 CPU 来确保更好的应用程序吞吐量。如果我们可以分配更多的 CPU 以获得更好的性能,那么 CMS 垃圾收集器是优于并行收集器的首选。
要启用 CMS 垃圾收集器,我们可以使用以下参数:
java -XX:+USeParNewGC -jar Application.java
G1(垃圾优先)垃圾收集器专为在具有大内存空间的多处理器机器上运行的应用程序而设计。它从JDK7 Update 4和更高版本开始可用。
它将堆内存分成多个区域,并在其中并行收集。G1 也会在回收内存后立即压缩空闲堆空间。但是 CMS 垃圾收集器会在停止世界 (STW) 情况下压缩内存。G1收集器将取代CMS收集器,因为它更高效。
在 G1 中收集器包含两个阶段;
打标
扫地
与其他收集器不同,G1收集器将堆划分为一组大小相等的堆区域,每个区域都是连续的虚拟内存范围。在执行垃圾回收时,G1显示了一个并发的全局标记阶段,以确定整个堆中对象的活跃度。
标记阶段完成后,G1知道哪些区域大部分是空的。它首先在这些区域收集,这通常会产生大量可用空间。这就是为什么这种垃圾收集方法被称为 Garbage-First 的原因。
要启用 G1 垃圾收集器,我们可以使用以下参数:
java -XX:+UseG1GC -jar Application.java
Epsilon 是一个不可操作的或被动的垃圾收集器。它为应用程序分配内存,但不收集未使用的对象。当应用程序耗尽 Java 堆时,JVM 将关闭。这意味着 Epsilon 垃圾收集器允许应用程序耗尽内存并崩溃。
此垃圾收集器的目的是测量和管理应用程序性能。活动垃圾收集器是在 JVM 中与您的应用程序一起运行的复杂程序。Epsilon 消除了 GC 对性能的影响。没有 GC 周期或读取或写入障碍。使用 Epsilon GC 时,代码是独立运行的。Epsilon 有助于可视化垃圾收集如何影响应用程序的性能以及内存阈值是多少,因为它会在耗尽时显示。例如,如果我们认为我们的应用程序只需要 1 GB 的内存,我们可以使用 -Xmx1g 运行它并查看行为。如果该内存分配不足,请使用堆转储重新运行它。请注意,我们必须启用此选项才能获得堆转储。
XX:HeapDumpOnOutOfMemoryError
如果我们需要充分利用应用程序的性能,Epsilon 可能是 GC 的最佳选择。但是我们需要对我们的代码如何使用内存有一个完整的了解。如果它几乎不产生垃圾,或者您确切知道它在运行期间使用了多少内存,那么 Epsilon 是一个可行的选择。
要启用 Epsilon 垃圾收集器,我们可以使用以下参数:
java -XX:+UseEpsilonGC -jar Application.java
ZGC 并发执行所有昂贵的工作,不会停止应用程序线程的执行超过 10 毫秒,这使其适用于需要低延迟和/或使用非常大堆的应用程序。根据 Oracle 文档,它可以处理数 TB 的堆。Oracle 在 Java 11 中引入了 ZGC。Z 垃圾收集器在其线程中执行其循环。它平均暂停应用程序 1 毫秒。G1 和 Parallel 收集器平均大约 200 毫秒。
在 Java 12 中,即使 Z 仍处于实验状态,Oracle 也添加了性能修复和类卸载。它仅在 64 位 Linux 上可用。但是,ZGC 通过一种称为指针着色的技术来利用 64 位指针。彩色指针存储有关堆上对象的额外信息。这是它仅限于 64 位 JVM 的原因之一。
ZGC会尝试自己设置线程数,通常是对的。但是如果 ZGC 有太多的线程,它会饿死你的应用程序。如果它没有足够的,您将创建垃圾比 GC 收集它的速度更快。ZGC 的阶段说明了它如何在不影响应用程序内存增长的情况下管理大型堆。
要启用 Z 垃圾收集器,我们可以使用以下参数:
java -XX:+UseZGC -jar Application.java
Shenandoah 是一个超低暂停时间的垃圾收集器,它通过与正在运行的 Java 程序同时执行更多的垃圾收集工作来减少 GC 暂停时间。CMS 和 G1 都执行活动对象的并发标记。Shenandoah 增加了并发压缩。
Shenandoah 使用内存区域来管理哪些对象不再使用,哪些对象是活动的并准备好进行压缩。Shenandoah 还为每个堆对象添加了一个转发指针,并使用它来控制对对象的访问。Shenandoah 的设计以并发 CPU 周期和空间换取暂停时间的改进。转发指针使移动对象变得容易,但激进的移动意味着 Shenandoah 比其他 GC 使用更多的内存并且需要更多的并行工作。但它通过非常短暂的停顿来完成额外的工作。
Shenandoah 在许多小阶段处理堆,其中大部分与应用程序并发。这种设计使 GC 可以有效地管理大堆。
Shenandoah 提供与 ZGC 相同的优势,具有大堆但更多的调整选项。根据您的应用程序的性质,不同的启发式方法可能非常适合。它的暂停时间可能不如 ZGC 的那么短,但它们更容易预测。
要启用 Shenandoah 垃圾收集器,我们可以使用以下参数:
java -XX:+UseShenanodoahC -jar Application.java
以上就是关于“7种Java垃圾回收器”的介绍,大家如果对此比较感兴趣,想了解更多相关知识,不妨来关注一下极悦的Java极悦在线学习,技术文档中的内容从入门到精通,细致全面,很适合没有基础的小伙伴学习,希望对大家能够有所帮助。
0基础 0学费 15天面授
Java就业班有基础 直达就业
业余时间 高薪转行
Java在职加薪班工作1~3年,加薪神器
工作3~5年,晋升架构
提交申请后,顾问老师会电话与您沟通安排学习