java FullGC问题解决示例

本文分析了系统A使用特定版本的FastJSON工具类导致Java虚拟机持久代频繁FullGC的问题。通过代码审查和测试验证,发现FastJSON的序列化方法在每次调用时创建新的类加载器,导致持久代内存不断膨胀。

java FullGC问题解决示例

环境

JDK版本:1.7.0_45
操作系统:linux

问题背景

某系统(后面称:系统A)接入监控平台之后,收到java虚拟机持久代FullGC报警通知。对此我们对这个问题进行了分析,分析过程如下:

查看JVM持久代统计信息:

执行命令:ps -ef|grep java, jmap -permstat 8698

JVM持久代类信息如下(部分数据):
在这里插入图片描述

持久代统计信息分析:

我们发现JVM持久代中90%以上的全部是com/alibaba/fastjson/util/ASMClassLoader@0x00000007这个类型的信息,故猜ASMClassLoader这个类与JVM频繁FullGC有关,并找到了系统A中与之有关的代码:

public static String getJsonResult(ResultDO<?> result) {
		View view = new View();
		if (result.isSuccess()) {
			view.setData(result.getData());
			view.setResult(result_success);
		} else {
			view.setResult(result_error);
		}
		view.setCode(result.getCode());
		view.setMsg(result.getMsg());
		view.setCount(result.getCount());
		return FastJsonUtil.serializeFromObject(view);
}

在这段代码中,每次调用serializeFromObject方法都会new SerializeConfig ,而SerializeConfig 内部会new ASMSerializerFactory,ASMSerializerFactory内部又会new ASMClassLoader 。
ASMClassLoader 继承自ClassLoader,是一个类加载器,而类加载器有一个特性,就是即使对于同一个类,不同的类加载器加载之后也会被JVM视为不同的类。
所以,每调用一次FastJsonUtil.serializeFromObject(obj)方法都会创建一个新的类加载器去加载该对象的序列化类,每个新的类加载器都会创建一个新类,导致JVM持久代不断增长,最终导致FullGC。

推测结论:

系统A使用了公司内部一个sofa:0.0.2-SNAPSHOT版本包中的FastJsonUtil.serializeFromObject(view)这个方法,而这个方法则会导致JVM持久代不断增加最终导致FullGC。

测试验证:

使用公司内部sofa:0.0.2-SNAPSHOT版本包。
调用FastJsonUtil.serializeFromObject(view)这个方法之前,执行命令:
ps -ef | grep java ,jmap -permstat 8698
在这里插入图片描述

这里JVM持久代中com/alibaba/fastjson/util/ASMClassLoader@0x00000007这个类型的类对象就很少了,不会出现sofa:0.0.2-SNAPSHOT版本所出现的情况。

调用FastJsonUtil.serializeFromObject(view)这个方法10000次之后,执行命令:

ps -ef | grep java ,jmap -permstat 8698

JVM持久代类信息如下(部分数据):
在这里插入图片描述

最终结论:

sofa:0.0.2-SNAPSHOT版本包中的FastJsonUtil.serializeFromObject(view)这个方法容易导致JVM持久代FullGC问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值