fastjson2
fastjson2 copied to clipboard
com.alibaba.fastjson2.util.DynamicClassLoader 类加载过多,造成jvm元空间内存使用达到99%
问题描述
我在线上服务排查发现,class loader数量巨多,导致监控内存飙升,元空间内存使用率达到 99.1% 通过arthas发现fastjson2中类加载数量很大,但是我自己项目中都是正常使用的fastjson,没有哪里可能有那么大的类加载。而且类加载数量一致持续升高,垃圾回收不掉,不知道是不是fastjson包里面哪里类加载过大还是什么问题
环境信息
请填写以下信息:
- JDK信息: [Openjdk 1.8.0_391]
- 版本信息:[Fastjson2 2.0.42]
重现步骤
如何操作可以重现该问题:
- 使用
xxx.xxx
方法 - 输入
...
数据 - 出现
...
错误
//可在此输入示例代码
期待的正确结果
对您期望发生的结果进行清晰简洁的描述。
相关日志输出
请复制并粘贴任何相关的日志输出。
附加信息
如果你还有其他需要提供的信息,可以在这里填写(可以提供截图、视频等)。
现在的信息无法诊断问题,需要你自己诊断装载了哪些类?使用fastjson2的方式也发下出来,方便大家诊断
现在的信息无法诊断问题,需要你自己诊断装载了哪些类?使用fastjson2的方式也发下出来,方便大家诊断
项目中使用的:com.alibaba.fastjson2.JSON#parseObject() 我跟到源码看了下,里面有使用到ThreadLocal,怀疑是没有remove造成了内存泄漏
我写了一个Demo,复现了这种情况 package com.mtt.javabase.json.fastjsonv2.mem;
import com.alibaba.fastjson2.JSON; import com.alibaba.fastjson2.JSONReader; import com.alibaba.fastjson2.JSONWriter; import com.alibaba.fastjson2.PropertyNamingStrategy; import com.alibaba.fastjson2.writer.ObjectWriterProvider;
import java.lang.management.ClassLoadingMXBean; import java.lang.management.ManagementFactory; import java.util.LinkedHashMap; import java.util.Map;
public class TestParseObject {
public static void main(String[] args) {
int count = 10;
for (int i = 0; i < count; i++) {
parseAddress(new DemoBean("test", "cn"));
}
}
public static void parseAddress(DemoBean form){
// 获取ClassLoadingMXBean实例
ClassLoadingMXBean classLoadingMXBean = ManagementFactory.getClassLoadingMXBean();
// 获取已加载类的数量
String s = JSON.toJSONString(form);
int loadedClassCount0 = classLoadingMXBean.getLoadedClassCount();
Map paramMap = JSON.parseObject(toUnderLineJSONString(form), LinkedHashMap.class);
// 获取已加载类的数量
int loadedClassCount1 = classLoadingMXBean.getLoadedClassCount();
System.out.println("第一次解析增加数量:" + (loadedClassCount1 - loadedClassCount0));
int loadedClassCount2 = classLoadingMXBean.getLoadedClassCount();
JSON.parseObject(s, DemoBean.class, JSONReader.Feature.SupportSmartMatch);
int loadedClassCount3 = classLoadingMXBean.getLoadedClassCount();
System.out.println("第二次解析增加数量:" + (loadedClassCount3 - loadedClassCount2));
}
public static String toUnderLineJSONString(Object data){
ObjectWriterProvider objectWriterProvider = new ObjectWriterProvider(PropertyNamingStrategy.SnakeCase);
JSONWriter.Context context = new JSONWriter.Context(objectWriterProvider);
return JSON.toJSONString(data,context);
}
}
package com.mtt.javabase.json.fastjsonv2.mem;
import lombok.Data;
import java.io.Serializable;
@Data public class DemoBean implements Serializable {
private static final long serialVersionUID = 3684004407642373704L;
private String address;
private String type1;
private String type2;
private String type3;
private String type4;
public DemoBean() {
}
public DemoBean(String address, String type1) {
this.address = address;
this.type1 = type1;
}
} ,第一种情况,加载类的数量会一直增加
现在的信息无法诊断问题,需要你自己诊断装载了哪些类?使用fastjson2的方式也发下出来,方便大家诊断
在JSON.toJSONString中添加JSONWriter.Context,好像就会导致最近的一个JSON.parseObject出现一个新增class load
ObjectWriterProvider 这个类要做单例
ObjectWriterProvider 这个类要做单例
OK