背景
当前在Java领域,JDK 8版本仍然享有广泛的使用,它支持了Parallel Scavenge、CMS和G1这几种垃圾收集器。因此,为了在业务应用中更加高效地进行开发和性能调优,我们需要对这些垃圾收集器的工作原理和特性有一个全面的理解和认识。
本文主要梳理了上述三种垃圾收集器(Parallel Scavenge、CMS和G1)的常用配置参数和使用场景,以便在实际应用中能够更加精准地调优和应对不同的性能需求。
简介
Parallel Scavenge是JDK8默认的垃圾收集器,其年轻代使用Parallel并行收集器进行垃圾回收;老年代使用Parallel Old并行收集器进行垃圾回收。
CMS在JDK1.5版本引入,JDK8中年轻代使用ParNew 收集器进行垃圾回购;老年代使用CMS收集器进行垃圾回收;极端情况下时会使用Serial收集器进行兜底Full GC。
G1一款在server端运行的垃圾收集器,专门针对于拥有多核处理器和大内存的机器,在JDK 7u4版本发行时被正式推出,在JDK9中更被指定为官方GC收集器。基于分区算法实现垃圾回收。
常用参数
Parrllel Scavenge回收器
-XX: +UseParallelGC
手动指定年轻代使用Parallel并行收集器执行内存回收任务。
-XX: +UseParallelOldGC
手动指定 老年代都是使用并行回收收集器
-XX:ParallelGCThreads
设置年轻代并行收集器的线程数。
-XX:MaxGCPauseMillis
设置垃圾收集器最大停顿时间(,(即STW的时间)。单位是亳秒
-XX : GCTimeRatio
垃圾收集时间占总时间的比例,用于衡量吞吐量的大小。默认值99
-XX: +UseAdaptiveSizePolicy
设置Parallel Scavenge收集器具有自适应调节策略
CMS回收器
-XX: +UseConcMarkSweepGC
手动指定使用CMS收集器执行内存回收任务。
-XX: CMSlnitiatingOccupanyFraction
设置堆内存使用率的阈值,一旦达到该阅值,便开始进行回收。
-XX: +UseCMSCompactAtFullCollection
用于指定在执行完Full GC后对内存空间进行压缩整理,以此避免内存碎片的产生。不过由于内存压缩整理过程无法并发执行,所带来的问题就是停顿时间变得更长了。
-XX: CMSFullGCsBeforeCompaction
设置在执行多少次Full GC后对内存空间进行压缩整理。
-XX: ParallelCMSThreads
设置CMS的线程数量
G1回收器
-XX: +UseG1GC
手动指定使用G1收集器执行内存回收任务。
-XX :G1HeapRegionSize
设置每个Region的大小。值是2的幂,范围是1MB到32MB之间,目标是根据最小的Java堆大小划分出约2048个区域。默认是堆内存的1/2000。
-XX:MaxGCPauseMillis
设置期望达到的最大Gc停顿时间指标(JVM会尽力实现,但不保证达到)。默认值是200ms
-XX: ParallelGCThread
设置STS工作线程数的值。最多设置为8
-XX:ConcGCThreads
设置并发标记的线程数。将n设置为并行垃圾回收线程数(ParallelGCThreads)的1/4左右。
-XX: InitiatingHeapOccupancyPercent
设置触发并发GC周期的Java堆占用率阈值。超过此值,就触发GC。默认值是45。
使用场景
Parrllel Scavenge回收器
最大化应用程序吞吐量。该垃圾收集器会动态调整分区大小。
CMS回收器
最小化GC的中断和停顿时间。
G1回收器
面向服务端你,针对具有大内存、多处理器的机器。
最主要是低GC延迟,并具有大堆的应用程序提供解决方案。
特定情况下用来替换CMS收集器:
- 50%的Java堆被活动数据占用
- 对象分配率或老年代提升频率变化很大
- GC停顿时间过长,0.5秒以上
- G1 GC当JVM的GC现场处理速度慢时,系统会调用应用程序线程加速垃圾回收过程
总结
通过上文的分析,我们可以认识到每种垃圾收集器都有其独特的特性和适用场景,并没有绝对的优劣之分。不过,考虑到JDK版本升级的趋势,采用G1收集器对未来的版本兼容性更为有利。
在实际的生产环境中,通常无需手动调整大量参数,因为JVM能够进行自我调优以达到较好的性能状态。然而,熟悉常用的参数配置不仅有助于我们更深入地理解JVM的垃圾回收机制,还能在必要时对垃圾回收过程进行精细控制,从而优化应用的性能表现。