首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Android 内存优化实践与总结(3)

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(即内存里占用内存最多的对象列表)。

  • Shallo Heap:对象本身占用内存的大小,不包含其引用的对象内存。
  • Retained Heap: Retained heap 值的计算方式是将 retained set 中的所有对象大小叠加。或者说,由于 X 被释放,导致其它所有被释放对象(包括被递归释放的)所占的 heap 大小。
第一眼看去 居然有 3 个 8M 的对象,加起来就是 24M 啊 这到底是什么鬼?

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

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

这里其实有两个问题:
  • 这几张图原图实际都是 1280x720,而在 1080p 手机上实测这几张图都缩放到了 1920x1080
  • 闪屏页面,其实这张图在闪屏显示过后应该可以回收,但是因为历史原因(和 JOOX 的退出机制有关),这张图被常驻在后台,导致无谓的内存占用。
优化方式:我们通过将这三张图从 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 后面对低端机型做了对应的优化。
返回列表