加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

fastjson class泄漏

发布时间:2020-12-16 18:46:49 所属栏目:百科 来源:网络整理
导读:问题描述 fastjson在jetty容器中序列化HttpServletRequest会导致class泄漏,严重时会导致meta区溢出,导致无限FGC。 fastjson序列化流程 fastjson通过动态生成代码提高序列化速度,序列化逻辑如下: Stringserialize(Objectobject){//先看是否已经存在对应的

问题描述

fastjson在jetty容器中序列化HttpServletRequest会导致class泄漏,严重时会导致meta区溢出,导致无限FGC。

fastjson序列化流程

fastjson通过动态生成代码提高序列化速度,序列化逻辑如下:

Stringserialize(Objectobject){

//先看是否已经存在对应的serializer
Serializerserializer=serializerCache.get(object.getClass());

if(serializer==null){

//通过动态生成代码的方式,创建新的序列器类
Class<?>serializerClass=createSerializerClass(object.getClass());
serializer=serializerClass.newInstance();
serializerCache.put(object.getClass(),serializer);

}
returnserializer.serialize(object);

}

如果传入的object类型是org.eclipse.jetty.server.Request,serializerClass.newInstance会出现异常。因此每次序列化org.eclipse.jetty.server.Request,都会生成一个serializerClass。即出现了class泄漏。

PS: org.eclipse.jetty.server.Request是jetty中HttpServletRequest的实现类,下面简称Request

newInstance()为什么会失败?

fastjson生成的serializerClass结构如下:

importorg.eclipse.jetty.server.Request;

classSerializer_XXX{

//Request中每个字段对应一个xxx_asm_field_type字段
Typecontext_asm_field_type;
TypeuserIdentityScope_asm_field_type;
//其他字段省略...

//构造函数
Serializer_XXX(){

context_asm_field_type=getFieldType(Request.class,"context");
userIdentityScope_asm_field_type=getFieldType(Request.class,"userIdentityScope");
//其他字段忽略...

}
}

构造函数会执行失败,原因是找不到org.eclipse.jetty.server.Request。

为什么找不到类?

问题涉及到的3个classloader,它们的结构如下:
ServerClassLoader -> WebAppClassLoader -> AsmClassLoader

Request的classloader是ServerClassLoader,Serializer_XXX的classloader是AsmClassLoader。


按照类加载的约定,加载Request类的流程如下:

wKiom1k-Tgax0r6dAAFB1aLwjBE321.png-wh_50

理论上Request是可以成功加载的。问题出在WebAppClassLoader,它违反了类加载的约定,没有让parent加载,而是自己直接加载,结果找不到,就直接抛ClassNotFoundException。
WebAppClassLoader的行为是可配置的,如果启动参数org.eclipse.jetty.server.webapp.parentLoaderPriority是true,它就会先让parent找,否则就自己找,默认是false

fastjson的问题在哪里?

fastjson实际是有考虑类加载的问题的,它是判断Request的ClassLoader是不是AsmClassLoader或AsmClassLoader的祖先。但是由于WebAppClassLoader违背了类加载的约定,fastjson的判断就变得不可靠了。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读