最近线上有一条机器在运行了10几天后出现告警,频繁出现fgc,在切断流量之后,从运维那边拿了应用的heapdump文件。在一开始出现fgc时,我就上了容器平台查看了gc日志,gc日志如下:

从日志中可以看出很明显优于metaspace空间不够造成的fgc,而且不断进行fgc,且metaspace空间回收不了。于是查看一下jvm启动参数,参数如下:

这里Metaspace和MaxMetaspace都设置成了256M,奇怪了gc日志中Metaspace才使用了165M就出现了fgc,难道是新加载的类90M的空间吗,这个可以肯定不是,如果不是新申请90M的空间这个原因引起的,那么就只有metaspace内存碎片引起的了。于是通过mat分析heapdump,发现 DelegatingClassLoader有1100多个,于是先查看一下 DelegatingClassLoader是个什么东西?其属于sun.reflect包下,代码如下:
classDelegatingClassLoader extendsClassLoader { DelegatingClassLoader(ClassLoader var1) { super(var1); }
证明其确实一个ClassLoader。
那到底是什么对象在引用这些ClassLoader呢,通过mat发现是 GeneratedMethodAccessor在引用这些ClassLoader,继续跟踪发现是mybatis的

线上应用出现频繁Full GC,分析发现由Metaspace空间不足引起。尽管Metaspace使用量仅为165M,但FGC仍在持续。通过MAT分析发现大量DelegatingClassLoader,进一步追踪到Mybatis的Reflector导致。MethodAccessor的创建和膨胀机制是问题关键,膨胀阈值默认为15,超过则使用DelegatingClassLoader。验证表明,调整inflationThreshold参数能有效减少Metaspace占用。解决方案包括增大Metaspace大小或限制MethodAccessor膨胀。

15万+

被折叠的 条评论
为什么被折叠?



