Serial GC(串行垃圾收集器)是一种单线程的垃圾回收器,主要用于小型应用或单核系统中,设计目标是简单和高效,尤其适合堆内存较小且对吞吐量要求不高的场景。Serial GC 是JVM最早期的垃圾回收器之一,虽然现在大多数场景下都被更先进的GC替代,但它在一些特定场合仍然有其用武之地。
Serial GC 的核心特点是所有垃圾回收工作都是单线程串行执行的,并且在回收期间会完全暂停应用程序的所有线程(Stop-the-World)。它分别在年轻代和老年代使用不同的算法进行垃圾回收:
年轻代GC:
老年代GC:
单线程执行:
Stop-the-World:
简单高效:
适合小型堆内存:
启用Serial GC:
-XX:+UseSerialGC
:通过此参数可以在JVM中启用Serial GC。默认情况下,JVM会根据系统配置自动选择GC,但在一些小型应用或嵌入式设备上,Serial GC是默认选择。堆内存设置:
-Xms
和 -Xmx
:通过这两个参数可以设置JVM的初始堆内存和最大堆内存大小,这对于Serial GC尤其重要,因为它适合小内存应用。小型应用:
嵌入式系统:
单核或少核系统:
测试或开发环境:
Serial GC 是一种简单的垃圾回收器,适合在小型应用和单核系统中使用。它的优势在于算法简单、管理开销小,适合在小堆内存和CPU资源有限的场景下使用。然而,由于它的Stop-the-World机制和无法利用多核的缺陷,它并不适用于现代的大规模、多线程、高并发应用场景。在这种情况下,像Parallel GC、G1 GC或ZGC等更高级的垃圾收集器会是更好的选择。
Parallel GC(Parallel Garbage Collector),又称为吞吐量优先垃圾收集器,是一种注重高吞吐量的垃圾回收器。它是JVM的默认垃圾回收器之一,特别适合在多核环境下并发执行垃圾回收任务,并且它的设计目标是最大限度地提高应用程序的吞吐量,而不是最小化垃圾回收时的停顿时间。
Parallel GC主要依赖并行执行垃圾回收任务,即在进行垃圾回收时,JVM会启动多个线程并发地执行垃圾收集工作。它的两个核心部分分别是年轻代垃圾回收和老年代垃圾回收:
年轻代GC(Young GC):
老年代GC(Old GC):
高吞吐量:
全堆暂停(Stop-the-World):
适合大堆内存和多核处理器:
配置简单:
常见的Parallel GC的配置参数如下:
启用Parallel GC:
-XX:+UseParallelGC
:启用Parallel GC,默认在许多JVM版本中即为启用状态。-XX:+UseParallelOldGC
:启用Parallel GC的老年代并行回收(一般在老JDK版本中需要手动启用)。GC线程数:
-XX:ParallelGCThreads=
:设置GC线程的数量,通常是系统CPU核心数的1到4倍,默认会根据硬件配置自动调整。最大GC暂停时间:
-XX:MaxGCPauseMillis=
:设置目标GC的最大暂停时间。JVM会尝试在这个目标时间内完成GC操作,但不能完全保证。吞吐量目标:
-XX:GCTimeRatio=
:控制GC时间占总时间的比例,默认值是99,表示GC时间占总时间的1%。自适应调整:
-XX:+UseAdaptiveSizePolicy
:启用自适应大小调整策略,JVM会根据运行时状况动态调整年轻代和老年代的大小,优化性能。Parallel GC特别适合以下场景:
高吞吐量需求:
多核服务器:
大内存应用:
Parallel GC是一种高吞吐量优先的垃圾回收器,适合在多核服务器和大堆内存的环境中使用。它通过并行化垃圾回收任务,提高了系统的吞吐量。然而,由于在垃圾回收时会暂停应用线程,因此不适合对延迟和响应时间要求较高的系统。
CMS GC(Concurrent Mark-Sweep Garbage Collector) 是一种低停顿垃圾回收器,专门为减少老年代的垃圾回收停顿时间而设计。CMS是JVM中的一种并发垃圾收集器,从JDK 1.4引入,主要用于对响应时间要求较高的应用,通常适用于有大量老年代对象的大型服务器应用。
CMS GC的全称是并发标记-清除垃圾收集器(Concurrent Mark-Sweep),它的垃圾回收过程主要分为以下几个阶段:
初始标记(Initial Mark):
并发标记(Concurrent Mark):
重新标记(Remark):
并发清除(Concurrent Sweep):
低停顿:
标记-清除算法:
并发回收:
内存碎片:
并发模式失败(Concurrent Mode Failure):
常用的CMS GC相关的配置参数:
-XX:+UseConcMarkSweepGC
:启用CMS垃圾收集器。-XX:CMSInitiatingOccupancyFraction=
:设置当老年代使用率达到N%时触发CMS垃圾回收,默认值是68%。-XX:+UseCMSInitiatingOccupancyOnly
:强制只在达到设定的使用率时触发CMS,不使用默认的自适应策略。-XX:+CMSClassUnloadingEnabled
:允许CMS回收方法区中的无用类,减少内存泄露风险。-XX:+CMSScavengeBeforeRemark
:在CMS GC的重新标记阶段之前,先触发一次年轻代GC,以减少老年代对年轻代的压力。-XX:+CMSParallelRemarkEnabled
:启用并行重标记阶段,以加快GC速度。CMS GC非常适合那些对响应时间要求高、应用需要较少停顿的场景,例如:
CMS GC通过并发标记和清除的方式减少老年代垃圾回收的停顿时间,使得它在响应时间敏感的应用中非常有用。但它也有内存碎片和CPU占用过高的问题,需要开发者根据具体情况选择适合的垃圾回收器。随着新一代垃圾收集器(如G1 GC和ZGC)的出现,CMS逐渐被淘汰,但在一些旧的高并发应用中,CMS依然被广泛使用。
G1 GC(Garbage-First Garbage Collector) 是一种适用于服务器端应用的低停顿垃圾收集器,旨在替代JDK中的CMS(Concurrent Mark-Sweep)垃圾收集器,从JDK 9开始成为默认的垃圾回收器。G1 GC的设计目标是以可预测的停顿时间控制垃圾回收的影响,同时在大内存环境中有较好的性能表现。
区域化堆内存管理(Region-based Heap Management):
Garbage-First策略:
混合回收(Mixed GC):
暂停时间可预测:
-XX:MaxGCPauseMillis
),然后根据这个目标动态调整GC行为。它尝试在满足该目标的同时进行尽可能多的内存回收。并发与并行回收:
压缩与内存碎片管理:
年轻代GC(Young GC):
初始标记(Initial Marking):
并发标记(Concurrent Marking):
最终标记(Final Remarking):
清除(Cleanup):
常用的G1 GC配置参数:
-XX:+UseG1GC
:启用G1垃圾收集器。-XX:MaxGCPauseMillis=
:设置目标最大GC暂停时间(毫秒)。-XX:InitiatingHeapOccupancyPercent=
:设置堆使用率达到多少时触发并发标记周期,默认45%。G1 GC适用于以下场景:
G1 GC通过分区回收、并行与并发的垃圾回收机制、灵活的暂停时间控制,为需要低停顿且大内存应用的Java程序提供了一个高效的垃圾收集解决方案。它在减少GC停顿时间和提高回收效率方面表现出色,同时克服了CMS在老年代GC和内存碎片管理上的不足。
ZGC(Z Garbage Collector) 是JDK中的一种低延迟垃圾收集器,旨在处理大内存堆的应用程序,同时保持极低的停顿时间。ZGC 是从 JDK 11 引入的,它主要针对以下需求设计:
低延迟: 主要目标是将GC的停顿时间控制在10毫秒以下,几乎不受堆大小的影响。因此,对于那些运行在大内存堆上的应用来说,它能提供非常低的暂停时间。
并发处理: 大多数的GC操作(标记、转移等)都是并发进行的,ZGC尽量避免长时间暂停应用线程。
区域化内存管理: ZGC将堆划分为不同的区域(regions),并在这些区域中进行垃圾回收和对象分配。与G1类似,但更加灵活。
指针压缩: ZGC使用染色指针(colored pointers)来减少内存碎片,并减少对象的移动成本。它不需要复杂的指针转换,使用64位虚拟地址空间来实现更高效的对象管理。
从JDK 11开始,ZGC可以通过以下命令行参数启用:
java -XX:+UnlockExperimentalVMOptions -XX:+UseZGC -Xms<size> -Xmx<size> YourApp
其中,-Xms
和 -Xmx
用于设置堆大小。
ZGC 适合那些需要在低延迟下处理大内存堆的应用,例如:
ZGC是为了应对大规模内存分配和垃圾回收问题而设计的,特别适合对延迟有严格要求的大内存应用。其最大的优势在于无论堆的大小如何,都能保持极低的停顿时间。
在JDK中,垃圾收集器的选择和配置对于应用性能的优化至关重要。JVM提供了多种垃圾收集器以适应不同的应用场景。以下是5种常见的垃圾收集器及其配置方法:
配置方法:
启用Serial GC:
-XX:+UseSerialGC
适用场景:
适合小型应用、单核CPU或嵌入式设备中,堆内存较小且对响应时间要求不高的场景。
配置方法:
启用Parallel GC:
-XX:+UseParallelGC
启用老年代并行回收(Parallel Old GC):
-XX:+UseParallelOldGC
设置并行GC线程数:
-XX:ParallelGCThreads=<N>
适用场景:
高吞吐量应用程序,适合在多核系统中使用,适合需要最大化CPU利用率的场景。
配置方法:
启用CMS GC:
-XX:+UseConcMarkSweepGC
设置CMS触发的堆内存占用比例(默认68%):
-XX:CMSInitiatingOccupancyFraction=<N>
只在占用率达到设定值时触发CMS:
-XX:+UseCMSInitiatingOccupancyOnly
适用场景:
适合需要低停顿时间的场景,如响应时间敏感的Web应用、在线系统。
配置方法:
启用G1 GC:
-XX:+UseG1GC
设置最大GC停顿时间目标(默认200ms):
-XX:MaxGCPauseMillis=<N>
设置并行GC线程数:
-XX:ParallelGCThreads=<N>
设置老年代并发回收线程数:
-XX:ConcGCThreads=<N>
适用场景:
适用于大内存应用,且需要低延迟和高吞吐量的场景。G1 GC将内存划分为多个独立的区域,提供灵活的垃圾回收策略。
配置方法:
启用ZGC:
-XX:+UseZGC
设置最大堆大小:
-Xmx<size>
设置并发GC线程数:
-XX:ConcGCThreads=<N>
适用场景:
超低停顿的场景,适用于超大堆内存的系统,尤其是对延迟极其敏感的大型应用。
这些垃圾收集器的选择应根据具体的应用需求和硬件资源进行合理配置。