Board logo

标题: Android 内存优化实践与总结(4) [打印本页]

作者: look_w    时间: 2017-11-18 20:58     标题: Android 内存优化实践与总结(4)

3. 我们也对 RDM 上的 OOM 进行了分析,发现其实有些 OOM 是可以避免的。下面这个 crash 就是上面提到的在 LsitView 的 adapter 里不停创建 bitmap,这个地方是我们的首页 banner 位,理论上 App 一打开就会缓存这张默认背景图片了,而实际在使用过一段时间后,才因为为了解码这张背景图而 OOM, 改为用全局缓存解决。

下面这个就是传说中的内存抖动:

实际代码如下,因为打 Log 而进行了字符串拼接,一旦这个函数被比较频繁地调用,那么就很有可能会发生内存抖动。这里我们新版本已经改为使用 stringbuilder 进行优化。

还有一些比较奇怪的情况,这里是我们扫描歌曲文件头的时候发生的,有些文件头居然有几百 M 大,导致一次申请了过大的内存,直接 OOM,这里暂时也无法修复,直接 catch 住 out of memory error。

4. 同时我们对一些逻辑代码进行调整,比如我们的 App 主页的第三个 tab(Live tab)进行了数据延迟加载,和定时回收。
这里因为这个页面除了有大图还有轮播 banner,实际强引用的图片会有多张,如果这个时候切到其他页面进行听歌等行为,这个页面一直在后台缓存,实际是很浪费耗内存的,同时为优化体验,我们又不能直接通过设置主页的 viewpager 的缓存页数,因为这样经常都会回收,导致影响体验,所以我们在页面不可见后过一段时间,清理掉 adapter 数据(只是清空 adapter 里的数据,实际从网络加载回来的数据还在,这里只是为了去掉界面对图片的引用),当页面再次显示时再用已经加载的数据显示,即减少了很多情况下图片的引用,也不影响体验。
5. 最后我们也遇到一个比较奇葩的问题,在我们的 RDM 上报上有这样一条上报
我们在 stackoverflow 上看到了相关的讨论,大致意思是有些情况下比如息屏,或者一些省电模式下,频繁地调 System.gc()可能会因为内核状态切换超时的异常。这个问题貌似没有比较好的解决方法,只能是优化内存,尽量减少手动调用 System.gc()
优化结果
我们通过启动 App 后,切换到我的音乐界面,停留 1 分钟,多次 gc 后,获取 App 内存占用
优化前:

优化后:

多次试验结果都差不多,这里只截取了其中一次,有 28M 的优化效果。
当然不同的场景内存占用不同,同时上面试验结果是通过多次手动触发 gc 稳定后的结果。对于使用其他第三方工具不手动 gc 的情况下,试验结果可能会差异比较大。

对于上面提到的 JOOX 里各种图片背景等问题,我们做了动态的优化,对不同的机型进行优化,对特别低端的机型设置为纯色背景等方式,最终优化效果如下:


平均内存降低 41M。
本次总结主要还是从图片方面下手,还有一点逻辑优化,已经基本达到优化目标。
四、总结上面写了很多,我们可以简单总结,目前 Andorid 内存优化还是比较重要一个话题,我们可以通过各种内存泄露检测组件,MAT 查看内存占用,Memory Monitor 跟踪整个 App 的内存变化情况, Heap Viewer 查看当前内存快照, Allocation Tracker 追踪内存对象的来源,以及利用崩溃上报平台从多个方面对 App 内存进行监控和优化。上面只是列举了一些常见的情况,当然每个 App 功能,逻辑,架构也都不一样,造成内存问题也是不尽相同,掌握好工具的使用,发现问题所在,才能对症下药。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0