查看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就可以了。