JVM fullgc 调优实践

场景:生产环境使用的是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

相关文章
相关标签/搜索