问题表现
首先是监控告警。随后查看监控发现 cpu飙升
image.png
然后此台应用挂掉
问题定位
1、日志提醒 metaspace oom,并且频繁出现
image.png
2、查看JVM metaspace: metaspace空间大小一直在256M附近
(线上JVM的metaspace配置参数:-XX:MaxMetaspaceSize=256m)
image.png
3、拉长日期查看:04月14日开始metaspace开始上涨(经确认04月14日业务开始上代码,并开始放量)
问题排查
1、使用jdk命令:jmap -clstats pid 打印类加载信息,显示有较多:com.alibaba.fastjson.util.ASMClassLoader
image.png
2、排障平台使用arthas命令:classloader 打印JVM中各个类加载器的数量,以进一步确认
其中ASMClassLoader实例数量比较多,对比其他业务应用ASMClassLoader实例数量一般为2个左右。而classloader数量较多,会占用较多的metaspace,且影响回收效率.
参考资料:
大量类加载器创建导致诡异 FullGC
metaspace内存结构
image.png
3、测试环境压测复现:
复现时遇到的问题:
- 大部分部分接口压测不会出现metaspace oom
- 部分接口压测会出现metaspace oom,出现oom接口的特点:返回类型为void
image.png
image.png
本地基于jmeter压测测试环境机器,然后使用jconsole连接服务器查看内存变化情况:metaspace增加
image.png
4、查看代码定位原因如下:
在工程的IndexController中,有重写easyopen框架的RespWriter
image.png
从代码可知,当方法返回为void时,会执行: new JsonResultSerializer()
image.png
继续跟进JsonResultSerializer
image.png
继续跟进SerializeConfig
image.png
继续跟进ASMSerializerFactory,可知此处在new ASMClassLoader
image.png
image.png
问题反思:
其实easyopen框架在@Api注解上已经提供了wrapResult = true/false的能力。