1, 频繁Minor GC
-Xmn 新生代大小 增大
-XX:NewRatio 老年代和新生代的比例 降低
目标:增大新生代,减少minor gc的频率
2,Minor GC后,大量对象存活进入老年代
-XX:SurvivorRatio s区经常满的情况下,适当减少该比例值,增大s区,减慢对象进入老年代
-XX:MaxTenuringThreshold 适当延长对象在s区的时间,比如提升到20次Minor gc后再进入老年代
3,老年代经常满,导致频繁full gc
优化新生代大小:增大新生代大小,避免因为s区装不下导致的对象提前晋升进入老年代
优化晋升策略:-XX:MaxTenuringThreshold 比如扩大晋升到老年代需要的Minor GC的次数
优化方式和前面两个差不多
4,老年代内存还很多,但是频繁的full gc
-XX:MetaspaceSize
-XX:MaxMetaspaceSize
检查元空间大小,可能是元空间过小导致的频繁 full gc
检查下代码是否有显式的调用系统GC
5,GC停顿时间过长
使用低延迟的收集器 G1
减小新生代,加快单次的GC时间,但是会导致GC频率上升
6,调优步骤
开启gc日志 :-XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintGCTimeStamps -Xloggc:/path/to/gc.log
可视化分析:
jstat -gc <pid> 查看各区域的使用情况和gc次数、时间
S0 S1 E O 内存使用率
YGC FGC young和full的gc次数
YGCT FGCT young和full的gc耗时,单位s
图中出现过E区满的情况下导致的Minor GC
GCViewer查看gc日志,查看gc时间、频率、内存区域变化趋势、吞吐量(程序运行时间/总时间)
分析结果处于上面哪种场景,调整参数,在压力测试下观察效果
- “笨”的收集器(Serial, Parallel) 直接触发 Full GC。
- “聪明”的收集器(CMS, G1) 会先尝试用 Major GC / Mixed GC 来解决问题,但如果它们失败了,最终还是会触发最糟糕的 Full GC
全部评论
(3) 回帖