内存测试是安卓性能测试的必测项之一,可见内存测试的重要性。因为如果一个 APP 的内存过高可能造成 OOM,程序崩溃,也可能造成应用卡慢,影响用户体验。简单的内存测试可以用 android studio 来监控 APP 的内存,观察 APP 在使用过程中,是否存在内存不断增高,却没有降低或持平的趋势,那很有可能存在内存泄露的问题。
说到内存泄露,现在很多 APP 用 LeakCanary 来测试内存泄露。对于主要由 Activity 组成的 APP 来说,LeakCanary 是一款很有用的内存检测工具。检测泄露的原理就是在 onDestory 时检测当前 Activity 是否有被引用,如果仍用引用则存在内存泄露。使用 LeakCanary 也很简单,拿到一个已经添加了 LeakCanary 的安卓包后,进行常规的功能操作,LeakCanary 会自动检测,并把泄露的 log 保存在单独的 leakcanary 应用里,也可以将 log 导出来。
对于不是主要由 Activity 组成的 APP 来说,LeakCanary 无法检测到更多的内存泄露。那么对于这种 APP,怎么检测出内存泄露呢?可以借助 android studio,在 APP 一开始启动时抓取内存 hprof 文件并记住当时的内存值,然后进行一些操作,观察内存是否一直往上涨或者点了 android studio 的 gc 按钮后,内存仍比一开始的内存值高很多,再抓取此时的 hprof 文件。使用 eclipse MAT 对比分析两个 hprof 文件即可知道两个时刻的内存差异,排查出内存泄露的原因。(注意:android studio 只能检测 debug 包,并且需要选对对应的进程)
还有另外一种方法可以检测非 Activity 的内存泄露。笔者以前在做非 Activity 的内存泄露测试时,使用上面的方法后每次排查到的基本都是 bitmap 未释放导致的内存泄露。所以做了一个检测非 Activity 内存泄露的工具,原理是参考 LeakCanary 的源码,检测 hprof 文件中是否存在 bitmap,如果存在,则使用 haha 库 (com.squareup.haha) 得出详细的引用路径。不过这个工具没有 LeakCanary 那么智能,需要人工将疑似有内存泄露的 hprof 抓取下来,再使用工具检测。
检测完 APP 是否存在内存泄露的问题后,我们还是需要将 APP 一些主要场景的内存值记录下来,方便不同版本的对比,控制 APP 因为功能的增加导致内存不断增加的情况。
一般从以下几个方面做内存优化:
1.降低图片占用的内存
2.避免在循环中 new 对象
3.避免对不再使用的对象持有强引用
4.建立缓存内存池,限定最大内存值