Java GC优化速查表
her0kings1ey
本文是基于Java Performance The Definitive Guide书中的优化GC章节最后的Summary部分作的总结。在阅读了英文版后,觉得还是翻译概括一下,以便日后的速查。
GC优化步骤
1 你的应用能容忍full gc带来的全局暂停么?
如果可以,那么选择Throughput collector吧,它在使用较少的CPU时间和堆空间的同时提供较好的性能;否则,选择并发收集器,堆空间较小的话CMS和G1都可以,比较大的堆空间的话最好使用G1吧。
2 默认的GC设置一般就足够满足性能要求了
如果觉得性能有问题需要优化GC,先确认性能瓶颈是在GC上。分析GC日志,看下具体GC花了多少时间以及它的频度。如果GC的时间小于3%,其实不太必要优化(除非你是要优化整体响应时间,如99%响应时间)
3 当前的GC暂停应用时间和你的目标接近么?
如果接近,只需要调整最大暂停时间可能就ok了。如果暂停时间离你的要求还很远,但应用的吞吐量还符合你的预期,你可以减小新生代的大小。不过,这样会导致更多但更小的暂停。
4 吞吐量是否是瓶颈?
那么你需要增加堆空间大小(或者至少增加新生代的大小)
但有时候更多不意味着更好:更大的堆同时意味着更长的暂停时间。即便是并发收集器,也意味着更长的新生代回收时间。这是因为更大的堆就会有更大的新生代,也就意味着更长的回收时间。
5 你正在使用并发收集器么,有遇到并发模式回收失败么?
如果你有足够的CPU,尝试增加后台并发GC的线程数,又或者通过调整InitiatingHeapOccupancyPercent来更早地启动后台的并发回收。对于G1算法来说,如果还有剩余的mixedGC 没有完成,并发模式不会启动。对于这种情况,尝试减少mixed GC count来加快全部mixed GC的完成。
你正在使用并发收集器么,有遇到因为提升到老生带失败导致的full GC么?
对于CMS收集器来说,提升失败暗示内存存在碎片化。我们能做得很少,某些情况下可以尝试使用更大的堆或者更早地启动后台回收线程,但不总是有效。对于这种情况,更好的解决方案是使用G1收集器。对于G1收集器,同样存在这种情况,但是可以通过更早地启动后台回收线程以及加快mixedGC进度。这样G1会在后台线程回收的过程中对内存进行压缩,集中到某些块中,减少碎片化的情况。
以上是该章的summary,实际上还有很多具体的情形没有说到。另外对于一些概念,如young gc、old gc、full gc的概念没有陈述清楚,后面希望有时间能对这一块进行总结吧。