Board logo

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

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

三、案例JOOX 是 IBG 一个核心产品,2014 年发布以来已经成为 5 个国家和地区排名第一的音乐 App。东南亚是 JOOX 的主要发行地区,实际上这些地区还是有很多的低端机型,对 App 的进行内存优化势在必行。
上面介绍了 Android 系统内存分配和回收机制,同时也列举了常见的内存问题,但是当我们接到一个内存优化的任务时,我们应该从何开始?下面是一次内存优化的分享。
1. 首先是解决大部分内存泄露。不管目前 App 内存占用怎样,理论上不需要的东西最好回收,避免浪费用户内存,减少 OOM。实际上自 JOOX 接入 LeakCanary 后,每个版本都会做内存泄露检测,经过几个版本的迭代,JOOX 已经修复了几十处内存泄露。

2. 通过 MAT 查看内存占用,优化占用内存较大的地方。JOOX 修复了一系列内存泄露后,内存占用还是居高不下,只能通过 MAT 查看到底是哪里占用了内存。关于 MAT 的使用,网上教程无数,简单推荐两篇 MAT 使用教程[11],MAT - Memory Analyzer Tool 使用进阶[12]。
点击 Android Studio 这里可以 dump 当前的内存快照,因为直接通过 Android Sutdio dump 出来的 hprof 文件与标准 hprof 文件有些差异,我们需要手动进行转换,利用 sdk 目录/platform-tools/hprof-conv.exe 可以直接进行转换,用法:hprof-conv 原文件.hprof 新文件.hprof。只需要输入原文件名还有目标文件名就可以进行转换,转换完就可以直接用 MAT 打开。

下面就是 JOOX 打开 App,手动进行多次 gc 的 hprof 文件。
这里我们看的是 Dominator Tree(即内存里占用内存最多的对象列表)。

第一眼看去 居然有 3 个 8M 的对象,加起来就是 24M 啊 这到底是什么鬼?

我们通过 List objects->with incoming references 查看(这里 with incoming references 表示查看谁引用了这个对象,with outgoing references 表示这个对象引用了谁)

通过这个方式我们看到这三张图分别是闪屏,App 主背景,App 抽屉背景。

这里其实有两个问题:
优化方式:我们通过将这三张图从 xhdpi 挪动到 xxhdpi(当然这里需要看下图片显示效果有没很大的影响),以及在闪屏显示过后回收闪屏图片。
优化结果:


从原来的 8.29x3=24.87M 到 3.68x2=7.36M 优化了 17M(有没一种万马奔腾的感觉。。可能有时费大力气优化很多代码也优化不了几百 K,所以很多情况下内存优化时优化图片还是比较立竿见影的)。
同样方式我们发现对于一些默认图,实际要求的显示要求并不高(图片相对简单,同时大部分情况下图片加载会成功),比如下面这张 banner 的背景图:

优化前 1.6M 左右,优化后 700K 左右。
同时我们也发现了默认图片一个其他问题,因为历史原因,我们使用的图片加载库,设置默认图片的接口是需要一个 bitmap,导致我们原来几乎每个 adapter 都用 BitmapFactory decode 了一个 bitmap,对同一张默认图片,不但没有复用,还保存了多份,不仅会造成内存浪费,而且导致滑动偶尔会卡顿。这里我们也对默认图片使用全局的 bitmap 缓存池,App 全局只要使用同一张 bitmap,都复用了同一份。
另外对于从 MAT 里看到的图片,有时候因为看不到在项目里面对应的 ID,会比较难确认到底是哪一张图,这里 stackoverflow 上有一种方法,直接用原始数据通过 GIM 还原这张图片。
这里其实也看到 JOOX 比较吃亏一个地方,JOOX 不少地方都是使用比较复杂的图片,同时有些地方还需要模糊,动画这些都是比较耗内存的操作,Material Design 出来后,很多 App 都遵循 MD 设计进行改版,通常默认背景,默认图片一般都是纯色,不仅 App 看起来比较明亮轻快,实际上也省了很多的内存,对此,JOOX 后面对低端机型做了对应的优化。




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