GC调优入门笔记 (2)

不同应用程序的对象寿命分布图是不一样的,但是许多应用的大致分布都符合上面这个图,这为分代收集奠定了一个很好的事实基础:大部分对象都在年轻时死去。

比如在一个公园里扫落叶,腾出空地让行人行走。有一些树掉叶子特别厉害,一小会儿地上就掉满了;而另外一些树每小时只掉一两片叶子。假设清洁工为了省力,每过一段时间就清扫一次,扫完了则回到椅子上休息。如果我是清洁工,肯定会选择集中打扫那些掉得厉害的树,而且可能会以比较高的频率打扫;至于那些掉得不厉害的树,只要偶尔看一下,等落满的时候再打扫就好了。如果每次都要把所有的树下打扫一遍,为了照顾那些掉得厉害的树我的打扫频率需要很高,我会很累,而且打扫时间也会变长,效率降低。

除了串行收集器和G1之外,其他收集器默认使用以下分代模型:

GC调优入门笔记

默认分代模型

模型分为年轻代和年老代,年轻代分为eden和两个survivor,virtual空间代表JVM向操作系统预订但还未实际分配的空间。

调优指标 maximum pause time

pause time是指垃圾处理器停止应用程序的运行,专注于空间释放时所花的时间。如果使用的是并行垃圾处理器,可以通过-XX:MaxGCPauseMillis=<nnn>这个命令行参数设定期望的最大pause time。(如果未设置,默认没有最大时间要求)

垃圾处理器会维护每次垃圾收集pause time的均值和方差,当均值与方差的和大于设置的MaxGCPauseMillis参数时,垃圾处理器会认为停留时间目标未达到,然后调整堆的大小和其它的有关参数来试图达到目标。

此处的maximum pause time和下面即将提到的throughput是一对相爱相杀的姐妹。通常减小堆size会优化pause time(扫描、处理时间减少),但是堆变小造成GC频率升高,从而导致throughput下降。对于这两者,垃圾处理器的处理方式是优先达到设置的pause time目标,其次再达到throughput目标。

throughput

吞吐量通过GC时间比例测量。 GC时间比例 = GC时间 / (GC时间 + 应用运行时间),其中的GC时间包括所有代的GC时间。如果使用的是并行垃圾处理器,吞吐量可以通过-XX:GCTimeRatio=<nnn>设置,若<nnn>为19,则GC时间比例为1/(1+19)=5%,即垃圾处理的时间占总时间的5%。

如果GCTimeRatio未达到要求,垃圾收集器会增加年轻代和年老代的大小来降低GCTimeRatio

footprint

内存占用(memory footprint)指程序运行时占用和引用的内存大小。

如果前面两个目标达到了,垃圾处理器会自动收缩堆,直至其中一个目标不再满足(一定是throughput,因为堆变小会使停留时间变短),然后再试图满足这个目标。

promptness

及时性 (promptness)定义为对象死去之后到对象所占用的内存可以使用之前的时间。这个指标对分布式系统通常比较重要。

一般调优策略

如果堆已经达到maximum heap size但throughput目标还未达到,说明设置的maximum heap size太小,可以尝试将其设为接近物理内存但还不至于导致内存交换的值。如果还是达不到throughput目标,说明这个throughput目标对于当前平台上的内存大小来说过高了。

如果throughput目标已经满足,但停留时间过长,则可以增加maximum pause time目标。但这样throughput目标有可能又得不到满足了,此时需要根据自己的判断作一个折中。

如上文所说,throughput与pause time对堆大小的要求相反,是一对相互竞争的指标。它们之间的相互竞争可能造成的结果是:即使应用程序已经在稳定运行了,堆大小仍然在上下振动。这表明垃圾处理器努力在两者之间寻找一个平衡。

度量

以上所说的throughput等指标需要根据应用的不同特性去测量。比如要测一个web server的throughput,可以用一个自己写的client load generator;测试Solaris系统上服务器的内存占用,可以用pmap这个命令;若要测GC的停留时间,则可以通过命令行参数-verbose:gc直接观察JVM的诊断输出。

总结

本文定性介绍了GC调优的一些初级概念,为实际调优奠定基础。但仅有这些模糊概念是远远不够的,在理论和实践上还会作出其它总结,欢迎关注。

参考资料/推荐阅读

Java Platform, Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide 文中提到的资料,Oracle写的,具有官方指导意义

深入理解Java虚拟机 推荐看第4-5章,详细讲解了调优工具的使用以及几个调优实例

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxsww.html