目标• 掌握一些 GC调优的基本技巧和模式• 如何编写对 GC友好的代码
Steps
Measure
Set GoalTuning
Measure - Factors
• GC Factors– Footprint/Allocate Rate/LDS/Pause
Time/Throughput• APP Factors– Response Time/QPS
• System Factors– Load/CPU/IO
Measure - Tools
• GC Log• jstat• jmap• sar• top
• Case Show!
GC Myth
来源于 JavaOne2010 The Garbage Collector Mythbusters Session
Tuning Goal
Throughput Latency
JVM Choice
• 32 bit–在 linux上有 3G地址空间的限制;–通常而言分配给 JVM堆最好控制在 2G以下;
• 64 bit– pointer占用内存更多• 最好开启 -XX:+UseCompressedOOPS
–如机器内存和 CPU都满足的情况下, 64 bit is the better choice。
GC Choice
• Throughput more important– ParallelOldGC
• Latencies more important– Usually ParallelOldGC first,if not satisfied then
CMS.
Footprint
• Heap Size Starting Point• Calculate Live Data Size– Set –Xms,-Xmx to 3x to 4x LDS
Patterns
• Goal: 降低 FGC执行的频率• 可选方案– 增大 old;
• 在不放大 heap的情况下,可能会造成一些问题;• 放大 heap;
– 尽可能减少从 new晋升到 old的对象;• Tenuring Threshold、 Survivor Space Size;
– 优化系统性能。
• Case Show!
Patterns
• Goal: 降低 FGC执行的频率– cases• case 1
– ThreadLocal保存的对象未清除,导致 old gen一直占用很多;
• case 2– 默认的 Parallel GC的动态调整策略导致 to space总是很小,于是去掉了动态调整策略,并给予合理的 to space大小;
Patterns
• Goal: 减小 FGC造成的暂停时间• 可选方案–减小 Heap;– GC换为 CMS;–升级或增加 CPU。
• Case Show!
Patterns
• Goal: 减小 FGC造成的暂停时间– cases• case 1
– LDS很大,导致切换为 CMS后, CMS GC造成的暂停时间是够短,但 YGC比以前 parallel慢了很多,于是最后只好降低 New Gen的大小,同时放大 to space的大小,尽可能避免 CMS GC内存分配慢带来的问题;
• case 2– 40 G的 heap, 16 core cpu,在采用 Parallel GC时 FGC一次要 120s+,简单的切换为 CMS后,降低为 200ms+,出现过几次 promotion failed,降低触发比率解决。
Patterns
• Goal: 降低 YGC的执行频率• 可选方案–增大新生代;• 有可能造成 FGC频繁。
–优化系统性能,减少每次请求的内存消耗量。
Patterns
• Goal: 缩短 YGC造成的暂停时间• 可选方案–减小新生代;• 有可能会造成 new晋升到 old的对象增加;
–增加或升级 CPU。
Experiences
• ParallelOldGC Tuning–根据应用决定是否要启用 AdaptiveSizePolicy– Use NUMA
Experiences
• CMS GC Tuning– Tenuring Threshold Tuning
• MTT越大,晋升到 old的对象可能越少,同时可能会导致YGC耗时变长;
• MTT越小,晋升到 old的对象可能越多,同时可能会使得YGC耗时变短,但也就造成了 old的 GC更频繁,对于CMS而言,还会造成更多的内存碎片。
• Best behavior: bytes surviving per age decrease as age increases.
– Survivor Size Tuning• 当太多对象晋升到 Old时,可能会造成 YGC耗时变长,此时应考虑适当放大 Survivor Size;
Experiences
• CMS GC Tuning–碎片监测• -XX:PrintFLSStatiscis=2 –XX:+PrintCMSStatiscis
– GC Cycle Initiation Tuning• LDS & allocate rate,不能太频繁,也不能太晚
Experiences
• CMS GC Tuning–最重要的• 不要出现 promotion failed和 concurrent mode
failure。• promotion failed
– 降低触发比率;– 增大 survivor space或 old;
• concurrent mode failure– 降低触发比率;– 增大 old;
Experiences
• CMS GC Tuning–不同 case不同策略
• 如 YGC后存活的对象较少,可以考虑调小 survivor space以及 tenuring threshold,以降低 YGC的执行频率和耗时;
• 如 YGC后存活的对象较多,则需要调小新生代,调大Survivor Space,尽可能减少晋升到 Old的对象,此时如晋升的太多,则会出现 YGC耗时比较长,且 CMS GC频繁的现象。
• Case Show!
目标• 掌握一些 GC调优的基本技巧和模式• 如何编写对 GC友好的代码
Write GC-Friendly Code
• 避免 Autobox产生浪费;• 合理控制数据结构的大小,例如
List、Map、 StringBuilder等;• 合理使用 Reference;• 不要使用 Finalizers来回收资源;– no guarantees when they will be run,or that they will not
run at all.• 更好的处理 read-only的数据。
• Case Show!
目标• 掌握一些 GC调优的基本技巧和模式• 如何编写对 GC友好的代码
References
• <Step by step GC Tuning> by Tony• JDK 6 complete options