问题现象
从截图可以看出,程序刚启动发生了3次FullGc, 13次YGC
开启打印GC日志的命令
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps
GC详细日志如下
[GC (Allocation Failure) [PSYoungGen: 65536K->6408K(76288K)] 65536K->6416K(251392K), 0.0148227 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] [GC (Allocation Failure) [PSYoungGen: 71944K->10063K(76288K)] 71952K->10151K(251392K), 0.0088836 secs] [Times: user=0.00 sys=0.00, real=0.01 secs] [GC (Metadata GC Threshold) [PSYoungGen: 41843K->7930K(76288K)] 41931K->8026K(251392K), 0.0055550 secs] [Times: user=0.06 sys=0.00, real=0.01 secs] [Full GC (Metadata GC Threshold) [PSYoungGen: 7930K->0K(76288K)] [ParOldGen: 96K->7795K(89088K)] 8026K->7795K(165376K), [Metaspace: 20582K->20568K(1067008K)], 0.0237734 secs] [Times: user=0.02 sys=0.00, real=0.02 secs] [GC (Allocation Failure) [PSYoungGen: 65536K->4667K(120320K)] 73331K->12471K(209408K), 0.0032643 secs] [Times: user=0.00 sys=0.00, real=0.00 secs] [GC (Allocation Failure) [PSYoungGen: 119867K->10564K(136192K)] 127671K->18375K(225280K), 0.0078389 secs] [Times: user=0.03 sys=0.03, real=0.01 secs] [GC (Allocation Failure) [PSYoungGen: 136004K->12791K(207872K)] 143815K->21645K(296960K), 0.0098903 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] [GC (Metadata GC Threshold) [PSYoungGen: 173010K->15352K(210432K)] 181864K->24278K(299520K), 0.0093598 secs] [Times: user=0.02 sys=0.00, real=0.01 secs] [Full GC (Metadata GC Threshold) [PSYoungGen: 15352K->0K(210432K)] [ParOldGen: 8926K->20725K(139264K)] 24278K->20725K(349696K), [Metaspace: 34021K->34007K(1079296K)], 0.0524986 secs] [Times: user=0.09 sys=0.00, real=0.05 secs] [GC (Allocation Failure) [PSYoungGen: 195072K->11399K(306688K)] 215797K->32133K(445952K), 0.0121779 secs] [Times: user=0.02 sys=0.00, real=0.01 secs]. [GC (Allocation Failure) [PSYoungGen: 306311K->17380K(342016K)] 327045K->51832K(481280K), 0.0195859 secs] [Times: user=0.06 sys=0.00, real=0.02 secs] [GC (Metadata GC Threshold) [PSYoungGen: 137137K->25060K(401408K)] 171589K->61916K(540672K), 0.0181306 secs] [Times: user=0.03 sys=0.03, real=0.02 secs] [Full GC (Metadata GC Threshold) [PSYoungGen: 25060K->0K(401408K)] [ParOldGen: 36855K->45564K(206848K)] 61916K->45564K(608256K), [Metaspace: 56321K->56281K(1099776K)], 0.1520313 secs] [Times: user=0.39 sys=0.00, real=0.15 secs] [GC (Allocation Failure) [PSYoungGen: 400103K->16619K(488960K)] 445675K->62199K(695808K), 0.0124262 secs] [Times: user=0.06 sys=0.00, real=0.01 secs] [GC (Allocation Failure) [PSYoungGen: 484587K->30713K(498688K)] 530167K->82583K(705536K), 0.0273914 secs] [Times: user=0.06 sys=0.00, real=0.03 secs]
问题分析
从日志来看,FullGC三次都发生在 Full GC (Metadata GC Threshold)
old区离最大配置还很远,Metaspace区并没有真正释放空间,所以怀疑是Metaspace区不够用了
使用 java -XX:+PrintFlagsFinal -version 查看默认参数值为 21 MB,最大值为4096M = 4G
翻阅资料后,得知JDK8中,-XX:MaxMetaspaceSize是没有上限的,与机器内存相关,但初始的默认值只有21M,所以得出结论是,因为metaspace空间不足导致发生了FullGC
解决方案
JDK1.8之后,永久代(PermGen)概念被废弃掉了,取而代之的是Metaspace的存储空间,它使用的是本地内存,而不是堆内存,它的大小与本地内存有关。
最终通过设置JVM启动参数-XX:MetaspaceSize=256M 解决了该问题。
-XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=256m