最近在学习Android内存优化方面的知识,下面做一下笔记。首先内存优化可以从三方面入手,分别是设备分级、Bitmap优化和内存泄漏。
- 设备分级
目标是针对设备性能的好坏使用不同的内存分配和回收策略。
- 设备分级
对低端机关闭复杂的动画或是某些功能;使用565格式的图片;使用更小的内存缓存。 - 缓存管理
使用统一的缓存管理机制,做到用时分配,及时归还。可以使用onTrimMemory回调,根据不同的状态决定释放多少内存。 - 进程模型
减少应用启动的进程数,减少常驻进程、有节制地保活。 - 安装包体积
安装包中的代码、资源、图片以及 so 库的体积,跟它们占用的内存有很大的关系。可以针对低端机发布轻量版本。
- Bitmap优化
- 统一图片库
使用统一的图片库Glide或Fresco等,进一步将所有Bitmap.createBitmap、BitmapFactory相关接口一并收拢。 - 统一监控
- 大图片监控
监控图片的宽高超过view宽高,开发测试中弹窗展示图片所在activity和堆栈,在灰度和线上环境上报后台。可以定期获取内存快照中的view和bitmap宽高比较。 - 重复图片监控
找出Bitmap像素数据完全一样,但是存在多个对象地存在,生成宽高、内存大小、重复次数、堆栈等信息上报后台。
可以使用HaHa库来实现(android8.0以下,因为8.0以后Bitmap中的buffer已经放到native内存中了),方法如下:- 通过haha库中 MemoryMappedFileBuffer 和 HprofParser 解析 hprof 文件,生成 Snapshot
- snapshot 通过 findClass 查找 Bitmap ClassObj 对象
- 通过 snapshot 获取 app 和 default 的 Heap 对象,通过 classObj 搜集Bitmap 的 Instance List
- 遍历上面收集的List,存入一个key为 mBuffer的hash 值,value 为 List 的Map中
- Map中去除没有重复的元素(value size 为1 就是没有重复的)并创建数据结构
- 获取调用栈,调用Instance.getNextInstanceToGcRoot获取
- 将信息汇总,构造一个对象,序列化为Json
- 图片总内存监控
统计所有图片占用地内存,在线上按照不同系统、分辨率等维度去分析图片内存地占用情况,该信息也可加入到崩溃日志中帮助分析OOM。
- 大图片监控
- 内存泄漏
主要目标是对内存泄漏建立持续的监控。
- Java内存泄漏
开发阶段可以使用LeakCanary,做Activity和Fragment的内存泄漏检测。线上环境使用Leakcanary有一定限制,有办法拿到hprof内存快照的话可以做进一步裁剪压缩上传后台,可参考快手客户端稳定性体系建设。 - OOM监控
- Native内存泄漏监控
- 针对无法重编so的情况
- 针对可重编so的情况
注:后两种关于so的还不太理解,目标是定期扫描分配与释放是否配对,以后再补充吧。