场景:生产环境使用的是Thrift提供的rpc接口服务,在作接口性能测试的时候,监控了JVM内存使用状况;html
1.经过定时检查jvm gc状况,发现fullgc触发的频率特别频繁,一分钟会有好几回的fullgc,如下为监控数据java
[root@wangfw-smarttrip-dev-7 ~]# jstat -gcutil 18154 S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 64.20 88.06 55.23 29.84 427 6.259 3 0.986 7.245 [root@wangfw-smarttrip-dev-7 ~]# jstat -gcutil 18154 S0 S1 E O P YGC YGCT FGC FGCT GCT 92.97 0.00 18.90 96.18 29.87 734 11.218 7 1.568 12.787 [root@wangfw-smarttrip-dev-7 ~]# jstat -gcutil 18154 S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 90.62 66.76 98.61 29.87 737 11.275 7 1.568 12.843 [root@wangfw-smarttrip-dev-7 ~]# jstat -gcutil 18154 S0 S1 E O P YGC YGCT FGC FGCT GCT 65.62 0.00 95.33 50.56 29.87 834 12.845 9 1.904 14.749 [root@wangfw-smarttrip-dev-7 ~]# jstat -gcutil 18154 S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 81.88 11.37 62.45 29.87 849 13.101 9 1.904 15.005 [root@wangfw-smarttrip-dev-7 ~]# jstat -gcutil 18154 S0 S1 E O P YGC YGCT FGC FGCT GCT 87.50 0.00 95.45 65.11 29.87 1198 18.710 13 2.576 21.286 [root@wangfw-smarttrip-dev-7 ~]# jstat -gcutil 18154 S0 S1 E O P YGC YGCT FGC FGCT GCT 85.94 0.00 19.50 49.17 29.82 1664 26.114 18 3.472 29.586 [root@wangfw-smarttrip-dev-7 ~]# jstat -gcutil 18154 S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 59.38 12.04 58.32 29.82 2227 35.113 23 4.326 39.439
2.而后经过jmap -heap pid 打印了对应的内存状况,发现老年代的内存大小较小;jvm
Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 1073741824 (1024.0MB) NewSize = 1310720 (1.25MB) MaxNewSize = 17592186044415 MB OldSize = 5439488 (5.1875MB) NewRatio = 2 SurvivorRatio = 8 PermSize = 134217728 (128.0MB) MaxPermSize = 134217728 (128.0MB) G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 349700096 (333.5MB) used = 295902608 (282.19471740722656MB) free = 53797488 (51.30528259277344MB) 84.61610716858368% used From Space: capacity = 4194304 (4.0MB) used = 3932160 (3.75MB) free = 262144 (0.25MB) 93.75% used To Space: capacity = 4194304 (4.0MB) used = 0 (0.0MB) free = 4194304 (4.0MB) 0.0% used PS Old Generation capacity = 125829120 (120.0MB) used = 84266376 (80.36267852783203MB) free = 41562744 (39.63732147216797MB) 66.96889877319336% used PS Perm Generation capacity = 134217728 (128.0MB) used = 40088296 (38.231178283691406MB) free = 94129432 (89.7688217163086MB) 29.86810803413391% used
缘由分析:性能
新生代通过几个步骤以后一直在往老年代转移,因为老年的的内存区域较小,达到临界点的时候直接就触发了fullgc;
解决方法:测试
java -Xms1024m -Xmx1024m -Xmn728m -XX:PermSize=128m -Xmn728m:设置年轻代大小为728m。整个JVM内存大小=年轻代大小 + 年老代大小 + 持久代大小; 主要须要搞明白分代垃圾回收流程 大部分对象在Eden区中生成。当Eden区满时,还存活的对象将被复制到Survivor区(两个中的一个),当这 个Survivor区满时,此区的存活对象将被复制到另一个Survivor区,当这个Survivor去也满了的时候,从第 一个Survivor区复制过来的而且此时还存活的对象,将被复制“年老区(Tenured)”。须要注意,Survivor的两个 区是对称的,没前后关系,因此同一个区中可能同时存在从Eden复制过来 对象,和从前一个Survivor复制过 来的对象,而复制到年老区的只有从第一个Survivor去过来的对象。并且,Survivor区总有一个是空的。同 时,根据程序须要,Survivor区是能够配置为多个的(多于两个),这样能够增长对象在年轻代中的存在时 间,减小被放到年老代的可能,这样子就能够控制老年代的大小而不会去触发对应的fullgc
参考文献:.net
JVM系列详解(经典): http://pengjiaheng.iteye.com/blog/552456code
JVM 设置:http://www.open-open.com/lib/view/open1340192635908.htmlhtm
Eden Old 对象转移详解: http://www.cnblogs.com/Mandylover/p/5208055.html对象
触发fullgc列子: http://blog.csdn.net/scugxl/article/details/50935863blog
线上fullgc例子1: http://blog.csdn.net/hengyunabc/article/details/24924843
线上fullgc例子2: http://caogen81.iteye.com/blog/1513345
jvm gc类型: http://www.importnew.com/13827.html