場景:生產環境使用的是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