Crash详情
这里记录一下之前查过的一个疑难Crash,当使用到已经回收的bitmap的时候,就会发生异常,堆栈一般都是系统堆栈,非常难查,堆栈如下所示:
crash堆栈:
解决方案:
这个解决方案是在crash的时候,dump内存,在下次进来的时候上报hprof文件,然后使用mat工具分析Hprof文件,找到bitmap的引用链。
直接搜索recycled的bitmap,一般都能搜索到。
select * from android.graphics.Bitmap bitmap where bitmap.mRecycled = true
- 如果第一种方法搜索出来的bitmap比较多的话,就需要根据bitmap的hashcode算出bitmap的shadow$monitor_值。
对于无锁对象object的shadowmonitor_不是一个固定的值,是虚拟机私有的实现,不过一般而言,我们只关心32位中的前四位,前四位一般都是存储的锁信息,当对象无锁的时候,一般都是1000。
shadow$monitor 通过位与运算 0x0FFFFFFF,前四位一定是0,后面28位原封不动。
(hash值的计算规则)
通过将hashcode跟0x80000000或运算,大致就可得到shadow$monitor_的值,由于mat不支持或运算,所以要提前计算一下。下面圈出来的就是bitmap的hashcode值。
如果使用0x80000000计算的值还是不对,那么就试下前四位为1001/1010/1011的情况(这几个值也是根据上面的identityHashCode方法倒推出来的),对应32为的值为0x90000000/0xA0000000/0xB0000000总有一个可以work。
select * from android.graphics.Bitmap bitmap where bitmap.shadow$monitor_ = xxx