垃圾收集提高了Java内存的效率,因为它从堆内存中移除了未被引用的对象,并为新对象释放了空间。Java虚拟机有八种类型的垃圾收集器。让我们详细看看每一个。
串行GC
这是GC最简单的实现,是为运行在单线程环境中的小型应用程序设计的。所有垃圾收集事件都在一个线程中连续进行。压缩在每次垃圾收集后执行。
当它运行时,它会导致“stop the world”事件,整个应用程序都会暂停。由于整个应用程序在垃圾收集过程中被冻结,因此在需要低延迟的实际场景中不建议这样做。
使用串行垃圾收集器的JVM参数是-XX:+UseSerialGC。
并行GC
并行收集器适用于在多处理器或多线程硬件上运行的中大型数据集的应用程序。这是JVM中GC的默认实现,也称为吞吐量收集器。
在年轻一代中,多线程用于较小的垃圾收集。在老一代中,单个线程用于主要的垃圾收集。在java培训中,有理论知识+实践项目,双管齐下,学以致用,让你深入浅出地学习java。
运行并行GC还会导致“stop the world event”和应用程序冻结。因为它更适合多线程环境,所以可以在需要完成大量工作并且可以接受长时间暂停的情况下使用,例如运行批处理作业。
使用并行垃圾收集器的JVM参数是-XX:+UseParallelGC.
并行旧GC
这是自Java 7u4以来的并行GC的默认版本。它与并行GC相同,只是它为年轻一代和老一代使用多线程。
使用并行垃圾收集器的JVM参数是-XX:+UseParallelOldGC。
CMS(并发标记扫描)GC
这也称为并发低暂停收集器。多个线程使用与Parallel相同的算法进行次要垃圾收集。主要垃圾收集是多线程的,就像并行旧GC一样,但CMS与应用程序进程并行运行,以最小化“stop the world”事件。通过java培训,你可以学习更多java垃圾收集技巧,以提高java技能。
因此,CMS收集器比其他GC使用更多的CPU。如果你可以为更好的性能分配更多的CPU,那么CMS垃圾收集器比并行收集器是更好的选择。CMS GC中不执行压缩。
使用并发标记扫描垃圾收集器的JVM参数是-XX:+UseConcMarkSweepGC。
G1(垃圾优先)GC
G1GC旨在取代CMS,并设计用于具有大堆大小(大于4GB)的多线程应用程序。它与CMS一样是并行和并发的,但与老的垃圾收集器相比,它的工作原理完全不同。
虽然G1也是一代的,但它并没有为年轻一代和年老一代分开的区域。相反,每一代都是一组区域,这允许以灵活的方式调整年轻一代的大小。
它将堆划分为一组大小相等的区域(1MB到32MB,取决于堆的大小),并使用多个线程扫描它们。在程序运行期间的任何时候,区域可能是旧区域或新区域。想要学习java更多知识和技能,可以考虑参加java培训,有经验丰富的专业讲师指导教学,有紧跟市场需求的实时课程,可以让你快速掌握这门技术,节约时间,少走弯路。
在标记阶段完成后,G1知道哪些区域包含最多的垃圾对象。如果用户对最短的暂停时间感兴趣,G1可以选择只疏散几个地区。如果用户不担心暂停时间或者已经陈述了一个相当大的暂停时间目标,G1可能会选择包含更多的区域。
因为G1GC会识别垃圾最多的区域,并首先对该区域执行垃圾收集,所以它被称为垃圾优先。
除了Eden、Survivor和Old memory区域,G1GC中还有两种类型的区域:
l Humongous—用于大型对象(大于堆大小的50%)
l Available—未使用或未分配的空间
使用G1垃圾收集器的JVM参数是-XX:+UseG1GC。
Epsilon垃圾收集器
Epsilon是一个什么都不做(no-op)的垃圾收集器,作为JDK 11的一部分发布。它处理内存分配,但不实现任何实际的内存回收机制。一旦可用的Java堆耗尽,JVM就会关闭。
它可以用于对延迟极其敏感的应用程序,在这些应用程序中,开发人员确切地知道应用程序的内存占用,甚至拥有(几乎)完全无垃圾的应用程序。否则,不鼓励在任何其他情况下使用Epsilon GC。
使用Epsilon垃圾收集器的JVM参数是-XX:+UnlockExperimentalVMOptions -XX:+UseEpsilonGC.
Shenandoah
Shenandoah是作为JDK 12的一部分发布的一个新GC。Shenandeah相对于G1的主要优势在于,它与应用程序线程同时执行更多的垃圾收集循环工作。G1只能在应用程序暂停时清空其堆区域,而Shenandoah可以在应用程序同时重新定位对象。
Shenandoah可以压缩活动对象,清理垃圾,并在检测到空闲内存后立即将RAM释放回操作系统。由于所有这些都是在应用程序运行时同时发生的,所以Shenandoah更加占用CPU资源。
使用Epsilon垃圾收集器的JVM参数是-XX:+UnlockExperimentalVMOptions-XX:+UseShenandoahGC。
ZGC
ZGC是作为JDK 11的一部分发布的另一个GC,并在JDK 12中进行了改进。它适用于需要低延迟(小于10ms暂停)和/或使用非常大的堆(TB)的应用程序。
ZGC的主要目标是低延迟、可扩展性和易用性。为此,ZGC允许Java应用程序在执行所有垃圾收集操作时继续运行。默认情况下,ZGC取消提交未使用的内存并将其返回给操作系统。
因此,ZGC通过提供极低的暂停时间(通常在2ms内),比其他传统GC带来了显著的改进。
使用Epsilon垃圾收集器的JVM参数是-XX:+UnlockExperimentalVMOptions -XX:+UseZGC。在java培训中,也有关于内存管理和垃圾回收的相关课程,学好这些技能和知识,保障程序稳定运行。
垃圾收集的优势
Java中的垃圾收集有很多好处。
首先,它使你的代码变得简单。你不必担心适当的内存分配和释放周期。你只需在代码中停止使用某个对象,它所使用的内存就会在某个时候被自动回收。
使用没有垃圾收集的语言(如C和C++)的程序员必须在他们的代码中实现手动内存管理。
它还使Java内存高效,因为垃圾收集器从堆内存中移除未引用的对象。这将释放堆内存来容纳新对象。
虽然一些程序员认为手动内存管理优于垃圾收集,但垃圾收集现在是许多流行编程语言的标准组件。
对于垃圾收集器对性能产生负面影响的场景,Java提供了许多选项来调优垃圾收集器,以提高其效率。