在工作过程中,遇到一个问题:SpringBoot 打包的可执行jar ,在重启或者发布的时候,会有多次的full GC。
{Heap before GC invocations=4 (full 1): PSYoungGen total 76288K, used 6533K [0x00000000fab00000, 0x0000000100000000, 0x0000000100000000) eden space 65536K, 0% used [0x00000000fab00000,0x00000000fab00000,0x00000000feb00000) from space 10752K, 60% used [0x00000000feb00000,0x00000000ff161468,0x00000000ff580000) to space 10752K, 0% used [0x00000000ff580000,0x00000000ff580000,0x0000000100000000) ParOldGen total 175104K, used 96K [0x00000000f0000000, 0x00000000fab00000, 0x00000000fab00000) object space 175104K, 0% used [0x00000000f0000000,0x00000000f0018010,0x00000000fab00000) Metaspace used 20379K, capacity 21094K, committed 21248K, reserved 1067008K class space used 2536K, capacity 2717K, committed 2816K, reserved 1048576K 2021-12-11T11:09:36.605+0800: 1.422: [Full GC (Metadata GC Threshold) [PSYoungGen: 6533K->0K(76288K)] [ParOldGen: 96K->6422K(175104K)] 6629K->6422K(251392K), [Metaspace: 20379K->20379K(1067008K)], 0.0299851 secs] [Times: user=0.13 sys=0.01, real=0.03 secs]
通过现象中的 [Metaspace: 20379K->20379K(1067008K)] 得出,full gc之后,Metaspace区没有释放空间, 且old区离最大配置还很远,所以怀疑是Metaspace区不够用了。
root@ps:/opt# java -XX:+PrintFlagsInitial # 需要配置环境变量 通过认证查找之后,可以算出 -XX:Metaspacesize为21720669B(大约20M) 查资料得出 ,在默认情况下,这个值大小根据不同的平台在12M到21M浮动
既然知道是因为Metaspacesize空间不足引起的,故而我们在容器启动的时候设定Metaspacesize的值即可
这就是为什么我们看到成熟项目的启动脚本里默认有Metaspacesize的原因。