并行垃圾收集器(Parallel GC、并行GC)是在多核CPU环境下的一种JVM垃圾收集算法,它可以在多个线程内并行执行垃圾收集功能,从而减少长时间GC对应用系统造成的影响。
下面主要介绍关于并行GC的使用和调优相关内容。
在什么时候使用并行GC
如果应用存在以下要求,那么就可以考虑使用Parallel GC:
- 侧重吞吐量:如果应用程序对事务吞吐量要求很高,并且可以容忍长时间执行垃圾收集,那么并行GC可能就是一个合适的选择。它主要通过允许垃圾收集与应用程序执行同时执行来优化吞吐量。
- 批量处理任务:应用程序如果涉及到批处理或者数据分析的任务,可以考虑使用并行GC。这些类型的应用程序经常执行大量的计算,并行GC有助于最小化垃圾收集过程对应用程序总体处理时间产生的影响。
- 中等以上堆内存:并行GC非常适合具有中等堆到较大堆的应用程序。如果应用程序需要大量堆来满足其内存需求,并行GC可以有效地管理内存并减少垃圾收集对应用程序的影响。
如何配置启用并行GC
可以在启动Java应用程序时传递以下参数,以启动并行GC(Parallel GC):
-XX:+UseParallelGC
这个JVM参数指的是JVM使用并行GC算法进行垃圾收集。但需要注意的是,在Java 8之前的JVM版本,不需要显式地指定垃圾收集算法,所有服务类JVM的默认垃圾收集器都是ParallelGC。
在Java 并行GC调优方面,下面介绍几个用于控制垃圾收集过程的关键JVM参数。包括:Heap和generation的大小参数、GC吞吐量相关参数、其他参数。
1.Heap和generation的大小参数
并行GC的调优涉及到整个堆的大小与年轻代和老代的大小之间的平衡。虽然较大的堆通常会提高吞吐量,但它也会导致执行GC期间消耗更长的时间。因此,找到“堆”和“代”的最佳大小至关重要。下面这些JVM参数支持调整堆大小和生成大小,以实现最佳GC配置。
(1) -Xmx
-Xmx
这个参数设置了最大堆大小,它设置了内存分配的上限。通过仔细评估并选择恰当的-Xmx值,可以控制整个堆的大小使得应用程序的可用内存和GC性能之间更加平衡。
(2) -XX:NewSize 、-XX:MaxNewSize、-XX:NewRatio
-XX:NewSize
-XX:MaxNewSize
-XX:NewRatio
这几个参数决定了分配新对象的Young Generation的大小。-XX:NewSize设置初始大小,而-XX:MaxNewSize用于控制内存上限,-XX:NewRatio用于配置年轻代和终身代之间的比率。通过这些值可以微调年轻代的大小和比例。
(3) -XX:YoungGenerationSizeIncrement
-XX:TenuredGenerationSizeIncrement
-XX:YoungGenerationSizeIncrement
-XX:TenuredGenerationSizeIncrement
这两个参数分别定义了年轻代和持久代的内存增量大小。年轻代和持久代的大小增量是内存分配和垃圾收集行为中的关键因素。增长和收缩是以不同的速度进行的。默认情况下以20%的增量增长,以5%的增量收缩。增长的百分比由参数-XX:YoungGeneratinotallow=和-XX:TenuredGeneratinotallow=进行配置。
(4) -XX:AdaptiveSizeDecrementScaleFactor
-XX:AdaptiveSizeDecrementScaleFactor
这个参数用于设置在收缩期间递减的比例因子。根据参数-XX:AdaptiveSizeDecrementScaleFactor=调整收缩的比例。如果增长增量为X%,则收缩的减少量为X/D%。
2.GC吞吐量相关的参数调优
为了实现垃圾收集最佳性能,控制GC暂停时间和优化GC吞吐量至关重要,GC吞吐量一般用“专门用于垃圾收集的时间量”与“应用程序执行时间量”的比例表示。以下是几个基于GC吞吐量的调优参数。
(1) -XX:MaxGCPauseMillis
-XX:MaxGCPauseMillis
这个参数允许开发人员指定垃圾收集所需的最大暂停时间(以毫秒为单位)。通过设置一个适当的值,开发人员可以调节GC暂停的时长,确保在可接受的范围内。
(2) -XX:GCTimeRatio
-XX:GCTimeRatio
这个参数使用公式1 /(1 + N)设置垃圾收集时间与应用程序时间的比率,其中N是正整数值。目的是定义垃圾收集所需的时间与应用程序执行时间的占比,以优化GC吞吐量。例如,-XX:GCTimeRatio=19。使用该配置的目标是将总应用程序执行时间的1/20或5%分配给垃圾收集。这意味着对于每20个时间单位(毫秒),在垃圾收集和应用执行总体时间的大约19毫秒中,大约有1个时间单位的时间将被分配给垃圾收集过程,而剩余的19个时间单位将专门用于应用的执行。这个参数默认值为99,意味着垃圾收集的目标时间为1%。
(3) -XX:GCTimePercentage
-XX:GCTimePercentage
这个参数更加直接,开发人员可以通过这个参数直接分配垃圾收集的时间与应用执行时间的期望百分比(GC吞吐量)。例如:设置“-XX:GCTimePercentage=5”表示分配总时间的5%用于垃圾收集,剩余的95%用于应用程序执行。
总之,‘-XX:GCTimeRatio‘或‘-XX:GCTimePercentage‘这两个参数都可以灵活地表示垃圾收集所需的时间。相比之下,使用“-XX:GCTimePercentage”比“-XX:GCTimeRatio”更加好理解。
3.其他参数
除前面几个JVM参数之外,还有一些其他参数也可用于调优并行GC算法的性能。
(1) -XX:ParallelGCThreads
-XX:ParallelGCThreads
这个参数允许开发人员指定并行GC算法中用于垃圾收集的线程数。通过基于当前CPU可用的内核数设置适当的值,充分利用多核系统的处理能力来优化吞吐量。线程太少或太多都不利于资源平衡,都可能导致性能不佳。
(2) -XX:-UseAdaptiveSizePolicy
-XX:-UseAdaptiveSizePolicy
这个参数允许根据应用程序对内存的需求动态调整年轻代和老年代的大小。默认情况下,“UseAdaptiveSizePolicy”处于启用状态。
启用:-XX:+UseAdaptiveSizePolicy
关闭:-XX:-UseAdaptiveSizePolicy
然而,默认情况下这个参数会根据应用程序对内存的需求动态调整年轻代和老年代的大小。动态调整可能导致频繁的“Full GC”,增加了GC时间。为了减少这类问题,我们可以通过设置-XX:-UseAdaptiveSizePolicy参数来禁用它,并减少GC时间。
执行并行GC调优
如果需要了解并行GC的性能,最好的方式是通过分析GC日志。GC日志包含了垃圾收集事件、内存使用情况以及其他相关的指标详细信息。
以下几个工具可以帮助分析GC日志:
- GCey
- IBM GC
- Memory Visualizer
- HP Jmeter
- Google Garbage Cat
通过使用这些工具,可以让内存的分配更加直观,能够识别潜在的瓶颈,并评估垃圾收集的效率。为并行GC的调优提供依据。
总之
通过调整堆的大小、代的大小和GC吞吐量相关参数等,可以优化垃圾收集过程,最大限度地提高内存利用率,最大限度地减少GC时长,提高Java应用程序的垃圾收集并效率,并释放Java应用程序的潜力。另外,对应用程序执行过程进行持续监控、分析和优化,是保持应用程序处于最佳性能的重要诀窍。