本文来自于腾讯优测公众号(wxutest),未经做者赞成,请勿转载,原文地址:https://mp.weixin.qq.com/s/806TiugiSJvFI7fH6eVA5w数组
做者:腾讯TMQ专项测试团队缓存
最近小优据说,隔壁的腾讯TMQ团队出了一本新书——《移动App性能评测与优化》,便借阅了一本,读完感受写得确实很赞。这本书体系化地介绍了移动应用性能评测与优化的方方面面,如内存,电量,流畅度,导航,网络优化和安装包瘦身等,强烈推荐你们阅读~微信
小优从书中摘取了第一章 “越用越卡为哪般——如何下降App的待机内存” 的内容。网络
本章介绍了各类内存使用状况分析的方法和一些优化技巧,让你们可以准确地了解应用内存的消耗状况,找出存在的内存问题,并在开发过程当中尽可能节约使用内存。app
本章共5节,上周给你们推送了第1节“内存测试新手入门”的内容,本周咱们继续讲解“规范测试流程及常见问题”,一块儿来看看吧!函数
最开始进行内存测试时,咱们可能还有些摸不着头脑,试着找了些工具,看了看教程就开始动手了。有时候由于问题比较明显,就真的发现了问题。再以后遇到相似的测试需求,咱们就会按上次的经验去作。有时候可能发现问题,也可能发现不了,还有些时候发现是甚至是在白费功夫。由于随着明显的问题逐渐被找出来,剩下的有都是更加复杂而不太明显的问题,甚至有些更是能够归属到优化范畴或者产品策略以内,而再也不是简单的内存问题。工具
随着经验的逐渐增长,咱们逐渐意识到,之前的不少测试方法都是随机乱测。对于较为成熟的软件,这类方法的测试有效性每每比较低,运气好了才会遇到问题。若是是较深层次的问题要么遇不到,要么遇到了也找不出缘由。所以,有必要总结出一套成熟的流程方法,可以考虑到各个方面,提升测试的有效性。性能
因为内存测试属于性能测试,Android系统又和Linux有不少相通之处。所以咱们能够参考常见的Linux性能测试方法和指标,来制定客户端性能测试方案。常见的测试方法包括Monkey/UIAutomator类的常规压力测试,大数据/操做的峰值压力测试,长时间运行的稳定性测试等。这些方法均可以叠加在内存测试的方案中,观察这类场景下的应用内存状况,常常可以发现相似内存泄漏或OOM的问题。测试
参考了常见性能测试的方案,以及总结了以往对内存性能测试的经验后,咱们总结出了一套进行内存测试的经验流程,供读者在制定测试计划时参考。大数据
一般用来进行内存测试的版本是纯净版本,不该该附加多余的Log和调试用组件。例若有些状况下,为了测试界面延迟/函数执行时间等性能,会加入一些桩点代码。在内存测试中这些代码是没必要要的,它们可能会分配临时内存,引发更多的GC,致使应用出现运行缓慢、卡顿等现象。
测试场景一般有两类,一类是当前有新开发或改动的某项功能,须要对该功能进行性能测试。所以测试场景主要针对该功能组织,包括功能的开启前,运行,结束后等测试点。
另外一类是总体性能,考察应用的常见场景,在综合使用状况下的性能指标。测试场景应当包括启动后待机,切换到后台,执行主要功能,以及反复执行各功能后。
在各种场景中,常常作为测试重点的有:
选取了测试场景后,用例设计也要考虑内存测试的特色。一些常见的方法是:
因为GC和广播机制的存在,应用内存一般都在不停得波动,幅度可能会达到几百K,所以执行时须要考虑这种状况。在采集数据时,须要屡次采集并计算平均值。
执行完成中,咱们就能够根据数据进行比较初步的分析以肯定方向。一方面是咱们熟悉的Dalvik Heap部分,既由Java代码直接分配的内存,能够经过IDE直接观察到使用状况,也可使用MAT进行细致的分析。
另外一方面,假如咱们发现Dalvik Heap没怎么增加,而其余部分增加了许多,这种状况下的分析就要复杂一些,咱们留待后面的章节再说。
随着测试的执行,随之而来的就是一大堆产生的数据,对产生的数据进行分析,找出可能存在的问题,以及问题可能的缘由是接下来的重点。
因为大部分Android应用是Java代码开发的,因此Dalvik Heap内存出现问题也是最多见的状况。常见的现象有如下几种:
随着功能的反复执行,Heap内存一直在持续增加。这种状况一般是出现了内存泄露,这种状况最适合用LeakCanary等泄露检查工具进行白盒测试分析。
代码执行时出现了频繁的GC,Heap Alloc内存大幅度波动。这种状况一般是分配了许多临时变量或数组,随后又被迅速回收,这种状况在肯定具体场景后适合使用Heap Viewer / Allocation Tracker等工具来查看具体分配的对象。
每次启动应用后,Heap内存相比之前版本稳定增加。这种状况一般出如今启动后待机或使用某功能后,多是由新功能及代码改动引入的固定内存增加。这种状况适合获取Heap Dump后进行多版本或功能使用先后的对此,可以迅速找到增加缘由。
Heap Alloc变化不大,但进程的Dalvik Heap PSS内存明显增长。这种状况比较少见,是因为分配了大量小对象形成的内存碎片,在后面的章节里会详细讲解,具体内容请见下一节。
在1.1节,咱们已经介绍了出现内存泄漏时的问题现象及分析方法,在这里咱们再以一个真实的例子介绍常见的几种内存问题和分析方法。
这是发生在手机管家4.x的某个版本上的案例,新版中加入了一些功能,开发人员估计新功能可能会分配几十到几百K的内存,所以咱们来进行内存方面的测试验证。当新功能的代码合入后,咱们发现应用启动后的内存增加超过了2M,这可大大超出了全部人的预期,必定是有什么地方出了严重的问题。
因为新加入了好几个功能,所以要逐个去排查。若是某个新功能的代码都在同一个package下,那么就可使用MAT的过滤功能来验证这部分代码是否使用了内存。如图1-7所示:
图1-7 使用MAT的过滤功能
通过一番筛选排查,发现内存中多出了一些新对象,多消耗了约300K内存,目前这并不能解释内存增加了2M的缘由。但仔细检查多出来的对象并清理掉不用的部分也是有帮助的。
通过检查,这部份内存是其余新功能使用的。对此咱们须要进一步确认,这些对象是不是有用的,仍是临时建立的。对于临时建立再也不使用的能够主动销毁,而保存着信息将要用到的也能够进行进行压缩裁剪,以进一步减小占用的内存。
在以上排查中,咱们确实发现了一些问题,但将一些不用的对象清理后再执行测试,整体内存并无出现明显的减小。如今看来,Dalvik Heap里分配的内存并无增长许多,说明问题是不能只在Dalivk Heap里就解决的。也许是别的部分出现了问题?接下面咱们就继续深挖下去。
通过上一轮的优化,在内存监视器里新版本的Heap内存表现已经比较好了,新功能只消耗了几十K到上百K内存。可是要注意的是,Heap内存并非应用的所有,咱们在设置或其余管理工具里看到的应用内存是应用整个进程的内存使用量。也有可能出现Heap部分彻底没有增加而其余部分增加的状况。
要观察进程的内存使用状况,就须要用到其余的观测工具,Android里最经常使用的观察进程内存的方法就是dumpsys meminfo <package name|pid>
命令。
对咱们的新版应用执行该命令,可以获得如下的输出结果:
在以上输出结果中,左边Pss Total列的数据标识进程各部分对真实物理内存的消耗,左下角的TOTAL值就是咱们在各类管理工具里看到的应用内存消耗。
而Android Studio等工具里显示的内存值,在这里是Dalvik Heap Alloc部分。根据以上的数据,咱们能够看到Dalvik Heap和Heap Alloc不是相等的,并且除了Dalvik Heap以外,还有其余不少部分也会消耗内存。
这时候咱们再对比一下旧版,看看是否也如此:
这时候就会发现问题了,Heap Alloc没增长多少,但Dalvik Heap Pss却涨了许多。而其余部分基本保持不变或有少许增加。可见问题仍是出现Dalvik Heap部分,但只靠检查分配的对象是看不出来问题的。
Java代码的内存分配和释放都是由虚拟机管理的,那么这个问题会是虚拟机的问题吗?下一节咱们来继续经过虚拟机部分机制的探索来探索这些内存增加的缘由。
更多精彩内容欢迎关注腾讯优测的微信公众帐号:
腾讯优测是专业的移动云测试平台,为应用、游戏、H5混合应用的研发团队提供产品质量检测与问题解决服务。不只在线上平台提供app自动化测试、云真机远程操控与调试、私有自动化测试工具XTest等多种质量检测工具,更为VIP客户配备了专家团队提供定制化综合测试解决方案。