问题背景
媒体应用播放音乐一晚上偶现程序崩溃
开始分析
dropbox log
java.lang.OutOfMemoryError: Failed to allocate a 72 byte allocation with 8 free bytes and 8B until OOM, target footprint 402653184, growth limit 402653184
at com.google.android.exoplayer2.ExoPlayerImplInternal.handleMessage(ExoPlayerImplInternal.java:563)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:219)
at android.os.HandlerThread.run(HandlerThread.java:67)
找到对应时间的log 发现此时heap大小超出了分配大小 并且此前已经多次Starting a blocking GC Alloc 均无法降低占用 并且报OutOfMemoryError 确认为内存溢出
查看系统当前分配heap大小
adb shell getprop | grep heap
内存溢出处log日志
07-08 04:12:05.811 4384 5221 I : Clamp target GC heap from 407MB to 384MB
07-08 04:12:05.811 4384 5221 I : Alloc concurrent copying GC freed 0(0B) AllocSpace objects, 0(0B) LOS objects, 0% free, 383MB/384MB, paused 39us total 943.805ms
07-08 04:12:05.811 4384 5102 I WaitForGcToComplete blocked Alloc on HeapTrim for 2.844s
07-08 04:12:05.811 4384 5102 I : Starting a blocking GC Alloc
07-08 04:12:05.811 4384 4408 I : Waiting for a blocking GC Alloc
07-08 04:12:05.811 4384 4384 I : Waiting for a blocking GC Alloc
07-08 04:12:05.811 4384 5221 W : Throwing OutOfMemoryError "Failed to allocate a 192 byte allocation with 72 free bytes and 72B until OOM, target footprint 402653184, growth limit 402653184" (VmSize 7736116 kB)
07-08 04:12:05.811 4384 4486 I : Waiting for a blocking GC Alloc
07-08 04:12:05.811 4384 5221 I : Waiting for a blocking GC Alloc
首先记录刚刚开始播放歌曲时内存快照文件 使如下命令
adb shell am dumpheap com.xxx.xxx /data/local/tmp/xxxx.hprof
取出hprof文件并拖入Androidstudio 打开可以看到retained 240M
然后播放歌曲3个小时候再取出内存快照查看
首先查看fragment和music
一通分析发现几个100M以上的都是因为引用了一个 ArrayList -> nowPlayingList 这里就基本定位问题了
继续看此list为何这么大 找到nowPlayingList变化的地方
private fun updateList(list: List<Music>?){
if(!list.isNullOrEmpty()){
nowPlayingList.addAll(list)
}
}
此处为歌曲每播放一首就会更新一下此列表但是此处list返回的是整个播放历史列表,每播放一首歌曲就会导致此列表追加之前所有的播放列表
因此更新数据先clear即可
private fun updateList(list: List<Music>?){
if(!list.isNullOrEmpty()){
nowPlayingList.clear()
nowPlayingList.addAll(list)
}
}
来吧,run!!再来3个小时音乐!!
再次播放歌曲3小时后内存快照
可以看到基本上已经没有问题了
收工!!!!!