剑客
关注科技互联网

Android内存泄露测试不再蓝瘦,香菇

在进行 Android 内存泄露分析时,面对成千上万个对象,你是否蓝瘦 , 香菇?作为测试人员你在进行内存泄露测试之后,是否有勇气告诉开发同事程序已经没有内存泄露,可以放心发布了?

众所周知,内存泄露测试难点在于准确的定位出泄露的对象。现在小哥有种方法通过一条命令就高效全面的得到 Android 程序内存泄露对象,让你不再蓝瘦,香菇!

Android内存泄露测试不再蓝瘦,香菇

1.Android内存泄露自动化分析方法

目前我知道的几种常用的 Android 内存泄漏方案主要有 MAT 、腾讯内部开发的 FinderLeakCanary 以及浏览器目前使用的方法。

几种方法,我们通过以下的几个纬度进行对比。

MAT Finder LeakCanary QB 方案
手动 / 自动 手动 手动 自动 自动
分析准确度
分析难度
分析效率
是否修改代码
应用场景 所有 所有 部分 所有

最原始的 Java 内存泄露分析方式,是通过 MAT 将测试操作前后的 Hprof 文件进行对比,然后根据对比结果来尝试识别出泄露对象,这种方法效率比较低。

如果使用腾讯的 Finder 工具来进行泄露分析,效率将会提高很多,但还是手动执行,也存在时间浪费的问题。

也可以使用 LeakCanary 或者腾讯自研的 LeakInspector 来测试,由于这两个工具是自动分析,效率会更加高效。但需要修改代码,把工具的 SDK 引入到工程中。此外针对不退出 Activity 的测试场景,不能很好的处理。

而我们的分析方法,一条命令就可以完成分析,并输出详细的泄露对象,以及调用关系。

从前面的表中可以看 LeakCanary 各方面都挺优秀,但是我们为什么没有使用它呢?这是因为 QQ 浏览器很多场景都是在 MainActivity 中进行的,比如打开网页,此时 MainActivity 并不会 Destroy ,直接使用 LeakCanary 无法进行泄漏分析,因此我们才考虑自己实现一个分析工具。

QQ 浏览器项目中,使用的分析工具叫做 HprofComparator ,这是我们自己开发的一个 Eclipse Application ,其原理与 Finder 的对比原理一致,但是加入了泄露分析的策略,可以通过命令行直接运行,更加的高效。

2.浏览器内存泄漏测试方案实施

1) 测试场景选择

做内存泄漏测试一定要全面的测试才敢通知项目组放心发布,目前 QQ 浏览器选择对所有的画面进行泄漏排查。

内存出现泄漏的前提条件一定是有新的内存分配,所以测试场景会选择有新对象创建的场景,并结合用户的使用场景和频率来确定优先级。测试场景主要有以下三种情况:

Ø  新画面打开

由于新的画面打开,就会创建新的 Activity ,并有许多其他对象被创建。

Ø  画面旋转

当屏幕旋转时, Orientation 设置发生了改变,当前显示的 Activity 会被重新创建。

Ø  滑动屏幕

滑动屏幕会使屏幕中显示的对象(比如浏览器小说阅读内容)创建。

2)内存泄漏分析

测试方法就是重复运行以上选择的场景,将整个测试过程分几个阶段获取到 Hprof 文件并保存。这个过程不详细阐述,下一部分会阐述我们的自动化方案。我们先看下拿到 Hprof 文件后人工分析的过程。

浏览器的内存分析工具运行的方法如下图所示。

Android内存泄露测试不再蓝瘦,香菇

运行完毕后将得到如下的分析结果文件。

Android内存泄露测试不再蓝瘦,香菇

需要重点查看的文件是 suspicion 文件,其内容如下图所示。

Android内存泄露测试不再蓝瘦,香菇

首先从图中可以看出 NewActivity 的对象泄漏了,该对象在操作过程中新创建出 5 个对象,内存增长了93696字节,内存中该对象的总数量为 13 个。

接着从图中的调用关系可以分析出,TextManager有一个listeners的数组持有了 NewActivity 的对象。

最后对比源代码查看输出结果可以一目了然的看出TextManager是一个单例的对象,而泄露对象应该是注册了 TextManager 的 ITextChangeListener,没有取消注册引起的泄漏。

我相信当测试人员把泄漏对象的根因连同 Bug 一起提交给开发时,开发同事们一定会觉得你很牛 X

此外泄露分析过程中还有一种常见情况,就是很多对象泄露是因为同一个原因,如下图是通过 Finder 对比得到的结果。

Android内存泄露测试不再蓝瘦,香菇

从这个图中可以看出泄漏对象非常多,如果我们逐个对对象进行原因分析的话,将浪费大量的时间,但是实际上这些对象的泄漏都是因为 NewActivity 的泄漏造成的。为了提高我们的分析效率, HprofComparator 对泄漏对象进行了去重处理。

Android内存泄露测试不再蓝瘦,香菇

如上图所示, BC 都为泄露嫌疑,从 BCCallstack 可以看出 BC 的父对象( B 引用 C ),因此只要 B 释放了, C 也会释放。这种情况时我们就会将 C 合并到 B ,最终结果输出 B 。如前面的 suspicion 文件内容中显示,有92个对象被 duplicate 到了 NewActivity 上。这样做之后输出结果会被大量的精简,需要分析原因的对象数量将会大大减少,节省了许多的时间。

3)关键字驱动的自动化方案

QQ 浏览器项目中一开始还是人工获取 Hprof 文件,这样做的测试效率比较低。为了提高测试效率我们也引入了自动化测试,但如何才能让自动化测试投入产出比比较高呢?

在分析了我们的测试场景和测试执行过程后,我发现内存泄露测试基本上可以分为做操作和获取 Hprof 文件,而操作又分为点击、滑动、旋转屏幕、等待和输入文字等。整个测试过程中除了需要确保操作是正确的外,并不需要功能的验证。

基于这些特点,我选择关键字驱动的自动化方案,就是为了以简便的方式来实现自动化,减少开发和维护成本。

如下图所示,在测试打开小说书城的场景,需要启动程序,然后点击小说入口,然后返回,需要重复打开小说的过程。在脚本中直接省略了打开应用程序的操作, repeat 关键字说明后续的步骤是需要重复操作的,而点击小说入口则仅以“小说”替代。这样就使测试脚本足够简单,任何刚入门的测试人员都可以完成。

Android内存泄露测试不再蓝瘦,香菇

在脚本要进行的操作都以关键字描述,测试时这些关键字都将转换成控件进行控件查找,或者转换成坐标直接点击。

Android内存泄露测试不再蓝瘦,香菇

以上的脚本还只是测试数据,我们需要一个测试驱动程序来分析测试脚本,以及执行对应的操作。在 QQ 浏览器项目中采用 Python 在实现驱动程序,并结合 Appium 实现自动化测试。驱动程序的执行流程非常简单,它就负责解析数据文件,然后执行关键字对应的操作。脚本的解析如下图的代码所示,每一个关键字会被处理成对应的命令,并存放到列表里。

Android内存泄露测试不再蓝瘦,香菇

以上测试运行过程中还会伴随着截图,用于后期分析时确保测试是正确执行的。当测试运行完毕后, hprof 文件将被 Pull 到电脑上,并使用自动分析工具进行泄漏分析。

4)测试运行情况

目前内存泄露测试已经加入到每个版本的常规测试中,每个版本平均能扫描出10+内存泄漏的问题。

手动测试和自动化测试对比情况如下图所示,内存泄露自动化测试的效率提升主要体现两个方面:

Ø  测试效率提升。人工测试 150+ 用例大概需要 5 人日,而现在可以一晚上运行完毕。

Ø  分析效率提升。人工通过 Finder 进行分析,需要近 5 个人日,而现在仅需要 1 天就可以完成。

通过这样的方法不仅保证了测试的准确性,也保证了测试的全面性,整体测试效率提升 85%

Android内存泄露测试不再蓝瘦,香菇

3.后续思考

由于浏览器的内存泄漏分析方法与被测试的应用无关 , 后续将考虑实现泄漏分析平台化 , 这样可以让更多的项目快速的应用起来 .

目前在浏览器项目使用了一种的基于模型的用例生成方法 , 但模型需要人工创建 ,以后 可以尝试对任意的应用程序自动生成模型并自动创建用例 .

版权所属,禁止转载

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址