Tools, 出来接活了--Android内存优化第三弹

引言

欲善其事, 先利其器.

1, 一图看懂Memory Monitor

Memory Monitor 是 Android Studio内置的, 官方的内存监测工具. 图形化的展示当前应用的内存状态, 包括已分配内存, 空闲内存, 内存实时动态等.

  • 顶部矩形指示当前调试的设备以及应用进程.

  • 图形区域:

    • 横向时间轴, 内存检测时间, 跟随滚动.
    • 纵向内存轴, 内存使用量, 根据应用使用动态分配.
    • 蓝色区域表示当前已分配使用的内存量.
    • 灰色区域表示剩余可使用的内存量.
    • 红色圈圈指示的是系统GC事件(内存有一定量的回收).
  • 工具栏:

    • ① GC按钮, 点击执行一次GC操作.
    • ② Dump Java Heap按钮, 点击会在该调试工程的captures目录生成一个类似这样”com.anly.githubapp_2016.09.21_23.42.hprof”命名的hprof文件, 并打开Android Studio的HPROF Viewer显示该文件内容.
    • ③ Allocation Traking按钮, 点击一次开始, 再次点击结束, 同样会在captrures目录生成一个文件, 类似”com.anly.githubapp_2016.09.21_23.48.alloc”, alloc后缀的文件, 并打开Allocation Tracker视图展示该文件内容.

2, 使用HPROF Viewer & Analyzer来分析hprof文件

Memory Monitor通过Dump Java Heap可以生成一个hprof的文件, 这个文件是Android特定的Heap和CPU分析文件, 记录了这段时间内的Java Heap变化.

2.1 关于Java Heap

由Java Heap文件可以看到如下数据:

  • 按类型显示对象申请的内存快照(内存大小);
  • 每次自动或手动触发GC时的样本数据;
  • 协助定位可能发生的内存泄露点:
    • 所有已经被destroyed的activity, 还可以从GC Root访问到.
    • 重复的String实例.

2.2 HPROF Viewer怎么看

还是用图说话:
-w1200

HPROF Viewer分成三个大块, 分别介绍下:

2.2.1 Class View

图中标①的View.

显示当前选中的Heap中的所有Class. 上方有两个可选列表, 分别是用来选择Heap区域, 和Class View的展示方式的.

Heap类型分为:

  • App Heap – 当前App使用的Heap
  • Image Heap – 磁盘上当前App的内存映射拷贝
  • Zygote Heap – Zygote进程Heap(每个App进程都是从Zygote孵化出来的, 这部分基本是framework中的通用的类的Heap)

可选展示方式:

  • Class List View – 类列表方式
  • Package Tree View – 根据包结构的树状显示
解释
Class Name 类名
Total Count 该类的实例个数
Heap Count 选定的Heap中该实例的个数
Sizeof 每个该实例占用的内存大小
Shallow Size 所有该类的实例占用的内存大小
Retained Size 该类的所有实例可支配的内存大小

2.2.2 Instance View

图中标②的View.
根据在Class View中选中的Class, 列表方式展示其所有实例的内存占用情况.

解释
Instance 该类的实例
Depth 深度, 从任一GC Root点到该实例的最短跳数
Dominating Size 该实例可支配的内存大小

2.2.3 Reference Tree

图中标③的View.
根据在Instance View中选中的实例, 显示其引用关系树.

此View中的列含义与Instance View一致.

在此View中可以右键点击instance, 进入代码:

2.3 HPROF Analyzer

另外, 在HPROF Viewer的右侧有一个”Analyzer Tasks”的按钮, 点击会进入HPROF Analyzer的hprof的分析界面:

分析任务包括:

  • 检测泄露的Activity
  • 查找重复的String实例

点击开始按钮后, 会在Analysis Results区域显示分析结果.

HPROF Viewer & Analyzer 可以用来对App的运行中的Java Heap做一个整体分析, 展示当前内存的具体到类和实例的分配情况, 以便检测到可能的内存泄露和重复实例.

3, Allocation Tracker

HPROF Viewer & Analyzer是整体的, 那么Allocation Tracker则是针对操作的分析.

Allocation Tracker可以协助我们分析在一个特定操作时, 有哪些对象被分配内存了. 这可以很方便的让我们知道方法调用的情况, 以便针对性的优化, 以提升性能和内存使用.

在Android Studio的Memory Monitor中点击”Start Allocation Tracking”, 在device中执行一个要分析的操作, 然后再次点击. 如下所示:

会生成一个alloc文件, 并打开:

可以按照两种方式展示:

  • Group by Method – 按照线程方法分组显示
  • Group by Allocator – 按照包分组显示

Method视图中的列含义如下:

解释
Method 方法
Count 该方法分配的实例总数
Size 该方法分配的内存总量(byte)

可以根据Count和Size分别排序, 找出产生实例多, 耗费内存多的方法, 结合代码分析, 以提升其性能.

4, MAT

Eclipse MAT是一个快速且功能丰富的Java Heap分析工具, 可以帮助我们寻找内存泄露, 减少内存消耗.

MAT可以分析程序(成千上万的对象产生过程中)生成的Heap dumps文件, 它会快速计算出对象的Retained Size, 来展示是哪些对象没有被GC, 自动生成内存泄露疑点的报告.

具体MAT的使用请移步鄙人翻译整理的MAT的使用手册

5, LeakCanary

LeakCanary是大名鼎鼎的square出的一款开源的用来做内存泄露检测的工具.

具体植入方式, 请参考LeakCanary README文档, 略过.

App植入LeakCanary之后, 在检测可能的内存泄露后, 会弹出Toast提示:

并在测试手机桌面生成一个Leaks的icon:

点击该icon进入Leaks界面, 可以比较清晰的看到内存泄露疑点:

6, adb shell dumpsys

在之前的一篇关于ADB使用的文中有聊到adb shell dumpsys命令, 该命令可以用户输出当前的系统状态信息.

其中就有关于内存的选项:

1
$ adb shell dumpsys meminfo com.udinic.perfdemo

输出信息如下:

Snip20161025_19

该命令常用来查看当前进程的的内存使用状态, 是一个总体的预览.

结语

正所谓善其事先利其器, 了解了内存分析工具的使用, 我们才能更好的分析内存问题, 从而得出解决方案或是明白从哪些方面去避免内存问题.

下一篇将以代码实例形式来说明下上面这些工具的具体使用, 敬请期待.