为什么要优化 ?
在讲为什么要优化之前先讲一下两个重要的优化目标,因为大部分的优化都是围绕着吞吐量及最大暂停时间进行的。如下,描述:
-
吞吐量
吞吐量表示 垃圾回收线程执行花费的时间与实际程序线程执行任务的时间之比。比如,在老板眼中的吞吐量就是,你一个小时中有多少个小时是为他工作的!(而不是带薪刷知乎)。
在大部分的服务器系统以及部分批处理的任务程序中,吞吐量当然是一个更加重要的指标。 -
最大暂停时间
由于程序JVM每隔一段时间都要进行一次GC,因为要让出资源所以会让程序的工作线程都挂起。所以最大暂停时间就是最长的GC 所花费的时间。在一般的金融或者c端产品中,为了更好的用户体验,对最大暂停时间的要求会比吞吐的更高。
所以现在当有人问起:你会GC优化吗? 你就可以回答:你要优化吞吐呢,还是最大延时呢!?
如何优化
优化最大吞吐量
吞吐量的优化目的在于减少GC的次数与总GC时间,通过减少GC的次数会让CPU减少因为GC带来的线程切换提高了执行效率。
步骤:
- 通过jstat 观察大部分的GC是发生在什么区之下。
- 通过加大对应GC频繁的generation的大小来减少GC次数。
可以通过加大整个堆的大小。或者是通过-XX:NewRatio,
-XX:NewSize等命令来修改年轻代,老年代的分配情况。 - 通过选择 UserParallelOldGC 来使用更高效率的高吞吐收集器 parallel compacting collector
优化最大暂停时间
步骤:
- 由于较大的暂停时间一般都是触发FullGC的时候才会出现,所以通过减小各generation的大小来增加GC次数,从而降低时间。
- 通过选择 CMS 或者G1 这些Concurrent 收集器来减低GC的时间。
不需要脑子的优化
通过设置-XX:+UseParallelGC选择使用parallel收集器,并且设置
-XX:GCTimeRatio=n(gc时间之比)以及-XX:MaxGCPauseMillis=n(最大暂停时间) 然后即可拿起薯片等待收集器自行调整堆大小来达到设置的目标,但是如果两个参数都设置,会以吞吐量为首要目标。
-XX:GCTimeRatio =nnn ,这里的rito的计算公式是:1/(1+nnn)。 比如当 -XX:GCTimeRatio=19 那么目标就是 5% 的垃圾回收时间
实例
以下展示两个仅仅通过修改堆大小及分配后的gc状态,实现通过调优之后减少了GC次数时间,提高吞吐。
before :
仅配置了堆大小为2G
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
3584.0 3584.0 2462.4 0.0 691712.0 621990.9 1610240.0 661094.9 57216.0 56112.3 6784.0 6483.1 9996 70.672 2 0.102 70.774
after:
第一版修改 设置总堆大小为4G,young generation : old generation = 2:1
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
4608.0 5120.0 0.0 3359.5 2062336.0 2011317.2 2072576.0 386632.2 59096.0 58032.5 6912.0 6629.8 3225 29.559 2 0.110 29.668
网友评论