查看bugly發現了一個 java.lang.StackOverflowError異常,剛開始沒有頭緒的,百度了半天也沒什麼結果。
bugly提示該異常表示棧溢出。 [解決方案]:JVM中會限定棧的深度,一旦超過該深度將會報錯,幾種常見的場景: 1、Layout佈局嵌套太深,導致棧溢出,建議控制在5層以下; 2、注意線程併發數,每個線程都會申請獨立的棧空間,不加控制時可能上百條線程一起把JVM限定的棧空間消耗完。 3、查看錯誤堆棧存是否存在代碼嵌套遞歸調用。
最後查看了bugly的跟蹤日誌,終於定位到了業務邏輯,發現其中有涉及到subList處理的函數
出現了遞歸調用,導致棧爆了
原因:
Unfortunately subList returns a view on the original list (this is documented)
which is implemented in AbstractList by use of a pointer to the parent list (this is not documented).
When calling certain operations on such a view, the operations are called recursively on the parent list
(this is absolutely not documented).If you call subList on a view you get a view on a view,
meaning you now have a parent hierarchy two levels deep.
大概意思是說:調用subList()得到一個child list,這個child list會維護一個指向parent list的引用。會一直遞歸調用到sbuList()方法,當數據很多的時候就棧溢出了。
怎麼解決這個問題呢?不要循環地調用subList(),並覆蓋原來的list。直接new一個新的list就可以了。