一次StackOverflowError排查,缘由居然和Dubbo有关!

前言

某天业务方的同事和我反馈,说系统出现了StackOverflowError.坦白说,Exception见得过了,可是Error却是不多出现,此时他的心情是这样的java

一波猛如虎的操做

咱们先来看血淋淋的案发现场面试

从异常栈中很明显发现出现了死循环,其实StackOverflowError绝大多数都是死循环、递归引发的.那么,这为何会出现循环调用呢?咱们根据这个溢出的案发现场查看源码json

若是你是用idea的话,他还会用图标提示你,这里会出现递归调用.框架

那么问题来了,这里究竟为何会循环递归调用?因为这个问题,是必然重现的,对于以前查看过我源码解析的老粉丝来讲简直是so easy.咱们触发场景,而后把断点打在案发现场,不断把断点放过,反复几回以后,以下图ide

通过上面的数据,咱们已经粗略看出死循环的迹象.咱们把目标锁定在了currencyavailableCurrencies. 为何这里会出现反复的循环呢?咱们查看一下Currency类的源码工具

public static Set<Currency> getAvailableCurrencies() {

	//省略...
}
复制代码

结合断点的序列化状况能够看出,currency进行json序列化的时候,须要去序列化availableCurrencies.而后getAvailableCurrencies()又包含currency,从而陷入了死循环.学习

本地重现

为了保证每一个粉丝都能参与其中,肥朝抽取了一个必然重现的最简模型.但愿肥朝公众号的粉丝都能一块儿参与进来,而不是每次看完分析事后,还有人一脸懵逼喊着666!this

public class FeiChaoDTO {

	private Currency currency;

	public Currency getCurrency() {
		return currency;
	}

	public void setCurrency(Currency currency) {
		this.currency = currency;
	}
}
复制代码
@Test
public void test() throws Exception {
	FeiChaoDTO feiChaoDTO = new FeiChaoDTO();
	feiChaoDTO.setCurrency(Currency.getInstance("CNY"));
	String json = JSON.json(feiChaoDTO);
	System.out.println(json);
}
复制代码

如何解决

很明显,出现这个问题的缘由是由于该同窗用了Dubbo里面的json序列化工具类,由于这个工具并不是是Dubbo主流功能,因此关注度不足,天然存在一些不完善的功能,而且在Dubbo2.6.x之后版本,已经标注为过时.另外咱们再看一下阿里开发手册搜索引擎

要解决这个问题方式很简单,既然要json序列化,那么就用主流的json序列化工具,不管是用fastjsongsonjackson都有对这些循环的状况作处理,仍是那句话,本公众号已经和各大搜索引擎长期合做,按照个人描述搜索,好比fastjson 循环引用,你想要的都有.固然细心的你可能发现,这些主流工具都不会去序列化availableCurrencies字段,Dubbo的这个序列化工具处理逻辑和主流的JSON工具处理仍是有些不一样,固然不用纠结,Dubbo自己定位就是RPC框架,就像肥朝公众号定位就是源码解析真实场景源码实战,JSON解析咱们能够选用上面的三大神器中的一个.idea

写在最后

近日有粉丝和肥朝反馈在面试过程遇到了以下的问题

我只想说,人家不问你也能够主动嘛.若是你是肥朝的粉丝,在工做、学习上遇到了什么问题,欢迎来撩,只要你主动,咱们的故事就开始了!

肥朝 是一个专一于 原理、源码、开发技巧的技术公众号,号内原创专题式源码解析、真实场景源码原理实战(重点)。扫描下面二维码关注肥朝,让本该造火箭的你,再也不拧螺丝!

相关文章
相关标签/搜索