[讨论] 一个频繁full gc的问题

mohenglyf 2014-08-28

我的一个线上应用,执行jstat -gcutil pid 1000

输出结果有如下表现:

 

S0     S1     E      O      P     YGC     YGCT    FGC    FGCT     GCT 

 0.00  57.24  99.76  64.77  26.61   6773  335.123   208   18.975  354.097

 56.31   0.00  14.04  64.96  26.61   6774  335.163   208   18.975  354.137

 56.31   0.00  25.47  64.96  26.61   6774  335.163   208   18.975  354.137

 56.31   0.00  42.20  64.96  26.61   6774  335.163   208   18.975  354.137

 56.31   0.00  71.42  64.96  26.61   6774  335.163   208   18.975  354.137

  0.00  54.91  12.00  65.05  26.61   6775  335.206   209   19.001  354.207

  0.00  54.91  22.45  65.05  26.61   6775  335.206   209   19.001  354.207

  0.00  54.91  36.07  65.05  26.61   6775  335.206   209   19.001  354.207

  0.00  54.91  52.06  65.05  26.61   6775  335.206   209   19.001  354.207

  0.00  54.91  65.17  65.05  26.61   6775  335.206   209   19.001  354.207

  0.00  54.91  81.02  65.05  26.61   6775  335.206   209   19.001  354.207

 56.48   0.00  20.17  55.86  26.61   6776  335.258   210   19.026  354.283

 56.48   0.00  38.29  55.01  26.61   6776  335.258   210   19.026  354.283

 56.48   0.00  59.06  55.01  26.61   6776  335.258   210   19.026  354.283

 

 

 

 

GC其实并不是很频繁,jvm参数设置了CMSInitiatingOccupancyFraction=65,所以old区使用量到达65%时,触发full gc。但是在发生第209次full gc时,old 区内存并没有被显著回收,还是65%,而是又经过了第210次full gc,old区内存才被回收至55%。

各位,有了解这是什么原因的么?

附上jvm 配置:

 

-server  -Xmx5500m -Xms5500m -XX:NewRatio=3 -XX:ParallelCMSThreads=4 -XX:PermSize=128m  -XX:+CMSClassUnloadingEnabled -XX:+DisableExplicitGC -XX:+PrintGCDetails -XX:+PrintHeapAtGC -XX:+PrintTenuringDistribution -XX:+UseConcMarkSweepGC -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:CMSFullGCsBeforeCompaction=0 -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=65

 

重点是,第209次执行full gc,为什么没有回收到内存呢?

RednaxelaFX 2014-08-31
mohenglyf 写道
重点是,第209次执行full gc,为什么没有回收到内存呢?


请让我再次建议与其用jstat -gcutil,还不如用jstat -gccause。后者比前者多显示一列,是当前正在进行的GC的“原因”。jstat只会认出GC暂停的阶段,每暂停一次计数就加一;CMS的一个周期里有两个暂停,而内存的回收是在第二个暂停之后才进行的。所以楼主说的情况再正常不过了。

CMS的一个周期包括:
1、CMS initial mark(第一个暂停)
2、CMS concurrent mark
3、CMS abortable pre-clean(可选)
4、CMS re-mark(第二个暂停)
5、CMS concurrent sweep <- 这里回收内存
6、CMS reset
(没标明是暂停的都是并发阶段)
Global site tag (gtag.js) - Google Analytics