浅谈GC调优
复杂的东西我们可不喜欢。一直以来,内存泄露,线程锁,GC调优这些东西处理起来都很痛苦。这三个邪恶的小伙伴带来的性能问题是最难复现的,这也使得修复这些问题有如噩梦一般。如果你不信的话,看一下LinkedIn最近关于性能调优的一篇文章就知道了。
尽管这篇文章很好的剖析了性能调优的过程,但它也很好的证明了这个领域的复杂性。LinkedIn的工程师进行GC调优改善吞吐量和延迟用的是下面这组参数:
知道这些参数的人请举手。知道一半的也行。为了让这组配置能满足LinkedIn对延迟时间和吞吐量的要求,处理过程大概是这样的:
收集信息了解当前的情况。在调优之前你得先知道底层的问题具体是什么。在上面那个案例中,看起来应该是频繁的长时间的GC暂停惹的祸,不过也有可能是锁或者内存泄露的问题,或者是别的什么问题。我们先假设你运气不错,GC暂停就是你要优化的地方了。
接下来,你得知道如何去收集GC暂停的数据。先跟这组参数打声招呼吧( -XX:+PrintGCDetails -XX:+PrintGCTimeStamps),它们会把GC暂停的数据给你的。
现在你得能够读懂这些数据。如果之前没有过经验的话,要在上百页的下面这些数据中掏出东西可不是什么美差事:
我再假设你有一根魔杖,能在这些日志中点出问题所在的地方。那现在你得分清楚CMS和G1的区别,知道在什么时候该用哪一个 (-XX:+UseParNewGC是新生代的,而-XX:+UseConcMarkSweepGC是指老生代的) ,还得弄明白eden区和suvivor区的区别,并正确的设置它们的大小(-XX:NewSize=6g -XX:MaxNewSize=6g -XX:MaxTenuringThreshold=2 -XX:SurvivorRatio=8)。
这只是个开始,如果你看过原文,你会发现最终的配置里面还包含GC工作线程的调优,堆碎片的优化甚至是操作系统页面交换的处理。好吧,如果之前听说过 -XX:ParGCCardsPerStrideChunk参数的也请举下手看看。
现在这篇文章可不止是发发牢骚而已了。如果上面这些东西让你感觉到一团糟的话,你或许会对我们实验室研发了一段时间的这个产品感兴趣,我们也很愿意将它分享给更多的人。就在上个月,我们挑选出一批用户,试用了Plumbr,它能对你的程序的GC行为进行分析,并给你推荐合适的参数配置。
如果你再也不想看到长时间的GC暂停,或者想确定下吞吐量或者延迟有没有问题的话——把你的邮箱留下,我们很乐意把这款GC优化工具的beta版发给你。
译注:到最后发现是篇软文?不过他们的网站上面确实有不少不错的文章,相信plumbr应该也是款不错的产品。
原创文章转载请注明出处:浅谈GC调优