List.subList方法导致的StackOverflowError

内推

【长期有效】欢迎加入字节跳动我的团队:内推链接

0x1.异常概览

java.lang.StackOverflowError
java.util.AbstractList$SubAbstractList.listIterator(AbstractList.java:308)
java.util.AbstractList$SubAbstractList.listIterator(AbstractList.java:308)
......
java.util.AbstractList$SubAbstractList.listIterator(AbstractList.java:308)
java.util.AbstractList$SubAbstractList.listIterator(AbstractList.java:308)
java.util.AbstractList$SubAbstractList.iterator(AbstractList.java:301)
java.util.AbstractCollection.toArrayList(AbstractCollection.java:349)
java.util.AbstractCollection.toArray(AbstractCollection.java:339)
java.util.Collections.sort(Collections.java:1863)

此crash只出现于Android 4.4及以下系统(<=JDK 6),而5.0(>=JDK 7)及以上版本系统未出现。

0x2.分析与解决

1)由于是特定系统版本bug,故上androidxref查看对应系统版本源码。(Android 4.4)
2)再观崩溃堆栈,Collections.sort(Collections.java:1863)方法中,会调用List.toArray方法再进行排序。Collections.sort如下:
Collections.sort
Question:直观上看代码,mNewCommingUsersTemp是一个ArrayList,ArrayList自己实现了toArray,不应该走到AbstractCollection.toArray(AbstractCollection.java:339),而且StackOverflow是由于AbstractList$SubAbstractList.listIterator(AbstractList.java:308)递归调用发生的。
Answer:所以可以肯定mNewCommingUsersTemp的引用指向应该从ArrayList对象变为了一个实现了List接口的其他对象。mNewCommingUsersTemp重新赋值就这一句:mNewCommingUsersTemp = mNewCommingUsersTemp.subList(0, NEW_COMMING_LIST_MAX_SIZE),所以基本锁定到subList的锅了。
3)关于subList方法。
mNewCommingUsersTemp一开始是个ArrayList对象,所以去找找源码中的subList方法,发现ArrayList并没有subList方法,在其父类AbstractList中找到了实现。
在这里插入图片描述
也就是每次subList方法都会新建个SubAbstractList对象,而它的实现方式是,引用父list,并记录sub的位置而已&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值