场景

新项目上线,为了观察项目运行情况,所以去监控看板去观察。好家伙,一看运行才一会儿就好几次Full GC,吓住我了。如果没有看板,可以通过命令行看:jstat -gccapacity pid。情况如下图:当我准备+HeapDumpBeforeFullGC去Dump快照下来分析的时候,仔细观察发现,事情好像比较简单,因为Full GC都发生在项目启动的时候。

问题排查

项目启动的时候触发Full GC,说明在项目启动的时候,老年代或者meta区可能频繁扩容导致的(JDK8+)。原因可能是:1、项目启动时加载了比较多或者比较大的对象,导致空间不够,频繁扩容;2、初始化空间太小,不够用,所以进行频繁扩容。一看内存使用情况,很充足,那应该就是后者了。

命令字段说明

jstat命令查看jvm的GC情况 (以Linux为例)jstat命令可以查看堆内存各部分的使用量,以及加载类的数量。命令的格式如下:jstat [-命令选项] [vmid] [间隔时间/毫秒] [查询次数]注意!!!:使用的jdk版本是jdk8. 类加载统计: Loaded:加载class的数量Bytes:所占用空间大小Unloaded:未加载...https://blog.csdn.net/shudaqi2010/article/details/104666951

命令一、jhsdb jmap --heap --pid pid  (查看堆信息)

 可以看到初始化meta空间只有20M多一点的大小(默认的)。

命令二、 jstat -gc pid (查看内存统计信息)

 可以看到实际的MetaspaceSize是195+M,已使用也有187+M。

原因

原因就基本知道了,由于初始时没有设置MetaspaceSize的大小,然后项目实际使用的Size接近200M,所以项目初始化的时候就进行Meta区的扩容,触发了Full GC。

解决方法

调整MetaspaceSize,JVM参数添加:

-XX:MetaspaceSize=200m

调整后的效果,Full GC就归零了:

命令三、jstat -gccapacity pid (查看GC统计信息)

总结

产生Full GC的原因一般就是老年代和Meta区的空间不够用了,至于为什么导致的?还得根据实际情况分析,借助一些分析工具(JVisualVM、Arthas)可以更好地定位问题。其实启动过程的Full GC也系统的运行也没什么大的影响,只是突然出现容易吓人。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐