GC调优自己的一些实战经验

启动full GC 超过3次

因为突发奇想,想看一下某个进程的GC情况,于是使用 jstat -gcutil 指令查看。如下:

S0     S1     E      O      M     CCS    YGC     YGCT    FGC    FGCT     GCT
0.00  96.40  12.74  34.36  94.81  92.49     27    0.218     3    0.275    0.492
0.00  96.40  13.50  34.36  94.81  92.49     27    0.218     3    0.275    0.492
0.00  96.40  14.26  34.36  94.81  92.49     27    0.218     3    0.275    0.492
0.00  96.40  15.10  34.36  94.81  92.49     27    0.218     3    0.275    0.492
0.00  96.40  15.10  34.36  94.81  92.49     27    0.218     3    0.275    0.492

应用启动过程中,Full GC 的次数就已达到3次。那么是因为什么原因导致的呢?

于是在启动参数添加 -XX:+PrintGCDetails 配置

[GC (Metadata GC Threshold) [PSYoungGen: 476551K->9446K(663552K)] 517040K->52498K(767488K), 0.0105495 secs] [Times: user=0.00 sys=0.02, real=0.01 secs] 
[Full GC (Metadata GC Threshold) [PSYoungGen: 9446K->0K(663552K)] [ParOldGen: 43052K->48675K(173568K)] 52498K->48675K(837120K), [Metaspace: 56828K->56828K(1099776K)], 0.2364243 secs] [Times: user=1.22 sys=0.00, real=0.24 secs] 

[GC (Allocation Failure) [PSYoungGen: 651776K->13149K(742400K)] 700451K->61833K(915968K), 0.0103157 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 

[GC (Allocation Failure) [PSYoungGen: 742237K->15344K(751616K)] 790921K->67078K(925184K), 0.0132358 secs] [Times: user=0.01 sys=0.00, real=0.01 secs] 

那么可以发现有一次是因为元空间的阈值达到造成的,于是查了下文档,JDK8中 默认元空间初始化大小阈值 -XX:MetaspaceSize 设置的是20M。首次使用不够会触发FGC。那么根据 该应用稳定后的所需的元空间,设置了为 128M后,发现启动过程full gc完全没有了

93.50   0.00  60.95  44.88  94.81  92.20     40    0.200     0    0.000    0.200
93.50   0.00  83.54  44.88  94.81  92.20     40    0.200     0    0.000    0.200
0.00  99.78  11.70  47.57  94.64  92.96     41    0.211     0    0.000    0.211
0.00  99.78  11.70  47.57  94.64  92.96     41    0.211     0    0.000    0.211

整个过程直到启动完成都没有full gc

使用G1收集器 survivor去总是100,minor GC启动过程中更频繁55次,而Parral GC,serail old组合 才 33次

建立发送消息任务,直接导致两次full GC

10000个对象取出+10000个对象合成,占用内存100M

解决方案