這可能是fastjson的一個bug,我使用最新版依然存在該問題。
在用做報表功能的時候,發現一旦單元格過多,大概有80-100個單元格,就會發生程序假死,CPU持續占用超過90%,內存持續占用超90%的情況,主要是報表頁面無法生成,這已經對我的業務產生了影響,不得不解決這個問題。
查看之前的代碼邏輯,發現原來的處理方式是直接用
JSONObject.toJSON(object) 來處理Javabean的,這樣處理簡單的對象是沒有問題的,但是對象如果復雜的話就會發生一些問題。
object對象過於復雜和大量時,用toJSOn解析就會出現CPU、內存一直飆升,JVM一直執行GC操作,但是無法回收內存,最后會報
java.lang.OutOfMemoryError: GC overhead limit exceeded 錯誤。
看到這里,我覺得這個內存泄漏問題我是不是可以直接修改JVM參數來擴大一下堆內存,設置后重新嘗試了一下,結果是一樣的,沒有效果。也從網上搜索到了說設置-XX:-UseGCOverheadLimit參數可以解決,試了也無果。然后就開始用mat分析一下我該段程序的dump文件,發現了一個地方有問題,也和控制台最終報的錯是同樣的異常:
com.alibaba.fastjson.util.IdentityHashMap產生了大量org.springframework.core.ResolvableType
這是因為IdentityHashMap 使用 System.identityHashCode作為key,而沒有使用 ResolvableType的hash值
這種情況主要的出現場景就是json解析的時候采用了泛型,泛型類沒有直接指定具體類型。
問題已經找到了,該解決了。我的解決方式是換成jackson解析,至於改fastjson源碼我沒有去試。
我的解決方式:
ObjectMapper mapper = new ObjectMapper(); //這里的JSONObject 我用的是fastjson的JSONObject,cell就是我需要解析的實體Map,其他類型的實體看具體情況具體分析 JSONObject object = mapper.readValue(mapper.writeValueAsBytes(cell), JSONObject.class);
結束🔚