某天業務方的同事和我反饋,說系統出現了StackOverflowError
.坦白說,Exception
見得過了,可是Error
卻是不多出現,此時他的心情是這樣的java
咱們先來看血淋淋的案發現場面試
從異常棧中很明顯發現出現了死循環,其實StackOverflowError
絕大多數都是死循環、遞歸引發的.那麼,這爲何會出現循環調用呢?咱們根據這個溢出的案發現場查看源碼json
若是你是用idea的話,他還會用圖標提示你,這裏會出現遞歸調用.框架
那麼問題來了,這裏究竟爲何會循環遞歸調用?因爲這個問題,是必然重現的,對於以前查看過我源碼解析的老粉絲來講簡直是so easy
.咱們觸發場景,而後把斷點打在案發現場,不斷把斷點放過,反覆幾回以後,以下圖ide
通過上面的數據,咱們已經粗略看出死循環的跡象.咱們把目標鎖定在了currency
和availableCurrencies
. 爲何這裏會出現反覆的循環呢?咱們查看一下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序列化工具,不管是用fastjson
、gson
、jackson
都有對這些循環的狀況作處理,仍是那句話,本公衆號已經和各大搜索引擎長期合做,按照個人描述搜索,好比fastjson 循環引用
,你想要的都有.固然細心的你可能發現,這些主流工具都不會去序列化availableCurrencies
字段,Dubbo的這個序列化工具處理邏輯和主流的JSON工具處理仍是有些不一樣,固然不用糾結,Dubbo自己定位就是RPC框架,就像肥朝公衆號定位就是源碼解析
、真實場景源碼實戰
,JSON解析咱們能夠選用上面的三大神器中的一個.idea
近日有粉絲和肥朝反饋在面試過程遇到了以下的問題
我只想說,人家不問你也能夠主動嘛.若是你是肥朝的粉絲,在工做、學習上遇到了什麼問題,歡迎來撩,只要你主動,咱們的故事就開始了!
肥朝 是一個專一於 原理、源碼、開發技巧的技術公衆號,號內原創專題式源碼解析、真實場景源碼原理實戰(重點)。掃描下面二維碼關注肥朝,讓本該造火箭的你,再也不擰螺絲!