前言
日常项目更新后启动,jstat看下内存使用情况(最近一直在优化内存使用方面),发现刚启动项目就有4次Full GC,这代码是不是写出了什么bug。这篇文章讲过对象分配内存的原则以及何时GC,问题来了分析就完了。
分析过程
1.先查看当前内存分布
jstat -gc
示例:
S0C Survivor1大小
S1C Survivor2大小
S0U Survivor0使用大小
S1U Survivor1使用大小
EC eden大小
EU eden使用大小
OC 老年代大小
OU 老年代使用大小
MC 元数据区大小
MU 元数据区使用大小
CCSC 压缩类空间大小
CCSU 压缩类使用大小
YGC 年轻垃圾回收次数
YGCT 年轻代垃圾回收消耗时间
FGC Full GC次数
FGCT Full GC耗时
GCT 垃圾回收总耗时
查看线上堆内存分布,老年代使用率5%,那么是什么触发了Full GC呢
2.分析GC日志
[Full GC (Metadata GC Threshold)
[PSYoungGen: 6903K->0K(504800K)]
[ParOldGen: 13057K->18883K(504800K)] 19961K->18883K(293376K),
[Metaspace: 33982K->33982K(111152k)], 0.1099454 secs] [Times: user=0.64 sys=0.00, real=0.11 secs]
年轻代,老年代都正常,但是好像元数据区大小不对,之前在看大神博客的时候好像初始化元数据区的大小是21M
java -XX:+PrintFlagsInitial MetaspaceSize
3.可能是因为元数据区扩容触发的Full GC
那么初始化指定元数据区大小试验一下
-XX:MetaspaceSize=200m
调整之后发现启动Full GC没了