本文来自于腾讯优测公众号(wxutest),未经做者赞成,请勿转载,原文地址:http://mp.weixin.qq.com/s/1_FKMbi1enpcKMqto-o_FQjava
做者:腾讯TMQ专项测试团队数组
最近小优据说,隔壁的腾讯TMQ团队出了一本新书——《移动App性能评测与优化》,便借阅了一原本读,读完感受写得确实很赞。这本书体系化地介绍了移动应用性能评测与优化的方方面面,如内存,电量,流畅度,导航,网络优化和安装包瘦身等,强烈推荐你们阅读~微信
小优从书中摘取了第一章 “越用越卡为哪般——如何下降App的待机内存” 的内容。本章介绍了各类内存使用状况分析的方法和一些优化技巧,让你们可以准确地了解应用内存的消耗状况,找出存在的内存问题,并在开发过程当中尽可能节约使用内存。本章共5节,本篇为第1节的入门内容,一块儿来看看吧!网络
在智能手机兴起的这几年中,咱们体验到了手机内存从256M到4G的巨大变化,进程可用的内存也从仅有16/32M到如今可使用2G以上的内存。与此同时,应用的功能也日益复杂,也有跟多的进程在同时运行,须要协做和互相切换的应用愈来愈多。app
在硬件资源增加后,应用开发者们会尽可能使用这些资源来实现更多的功能和效果,所以咱们面对着各类大量消耗内存的应用,依然会感受到内存是稀缺资源。咱们任然须要须要每一个应用开发者了解内存的消耗状况,并尽可能节约使用内存。框架
当软件实现了新功能后,准备发布版本前,每每须要进行一轮性能测试以肯定没有性能问题,这类测试一般包括功能的流畅度,电量消耗和内存使用状况等。工具
因为内存组成的复杂性,实际上并无简单通用的方法就可以发现全部的内存问题。下面的章节里,咱们会围绕一组案例展开,经过对案例的分析讲解各类内存测试的工具和方法。这些例子都是从真实的测试案例中提取的,通过加工后使得问题表现的更加明显。性能
接下来咱们以一个最多见的内存泄漏开始,做为最典型的内存问题,相似的状况可能在无数应用的无数版本中出现过,并且还会不断的在新版本里出现。对于这样的问题,咱们必需要准确识别出来。测试
在大部分应用中,常常会有一类功能是须要加载附加资源的,好比显示从网络下载的文本或图片。这类功能每每须要在内存中存放要使用的资源对象,退出该功能后,就须要将这些资源对象清空。若是忘了清理,或者是代码缘由形成的清理无效,就会造成内存泄漏。咱们的测试任务就是保证功能的正常,而且不会有遗留的内存对象形成泄漏。优化
要开始进行性能测试,测试工具是必不可少的。咱们通常都会优先使用SDK/IDE自带的工具,所以首先会想到的工具就是和IDE集成在一块儿的Android Device Monitor/Android Studio了。
大多数状况下,功能代码都是由Dalvik虚拟机里执行的Java代码实现的,所以主要的内存消耗也是由Java代码使用new分配的内存。Android Device Monitor和Android Studio可以方便的观察Heap Alloc部分的大小,进行初步的统计,还可以观察到GC发生时的内存变化状况。
图1-1 使用DDMS观察应用的内存消耗
图1-2 使用Android Studio观察应用的内存消耗
在图1-1中,咱们可以看到应用当前消耗了多少内存,以及各类不一样类型对象的初步统计。在图1-2中,Android Studio更进一步的将内存数据进行了图形化,这样就能过方便地看出GC(垃圾回收)状况和明显的内存趋势。若是存在明显的内存泄漏,那么在图中就会表现为随着功能的反复使用,内存值不断的升高,即便出现GC也无法降下来,如图1-3所示。
图1-3典型的内存泄漏
发现了内存泄漏,一般就能够交给开发去处理了。但咱们能作的并不仅是丢一个问题描述和复现路径过去,而是利用手头的工具,得到一些更详细的数据,可以使你们更快的定位和解决问题。这样分析内存得到详细数据的首选工具就是Eclipse Memory Analyzer(MAT)了。
Eclipse Memory Analyzer(MAT)是使用很是普遍的Java内存分析工具,功能强大。已经有不少关于它的详细教程,在本书中就再也不细述用法。本节内容主要介绍使用MAT在分析Android应用时的一些经常使用技巧。
一般咱们用MAT打开hprof文件后,可以在首页看到Top Consumers和Component Report等功能,使用这些功能可以快速定位一些大块的内存消耗。但对于Android应用的hprof文件,咱们在使用了Top Consumers统计使用状况后,每每只能看到如图1-4所示的状况:
图1-4 使用MAT分析内存构成
系统的资源类占据了很大一部分的内存,而其他的前几名也每每是系统类。这是因为从虚拟机角度不会区分系统框架和应用自身的对象,后面的1.4.3节会详细说明出现这种现象的缘由。
为了去除这部分对分析的干扰,咱们在用Android SDK提供的hprof-conv转换时须要增长一个参数:
hprof-conv [-z] <infile><outfile> -z: exclude non-app heaps, such as Zygote
另外一种可替代的方法是使用OQL。若是hprof文件是已经转换过的,能够在数据中寻找应用的Application类对象,将对象地址转换为10进制后输入如下查询语句:
select * from instanceof java.lang.Object s where s.@objectAddress > 1107296256
使用-z参数转换或OQL查询后获得的对象集合就只包含应用代码分配的部分了。在此基础上使用MAT提供的Top Consumers和Component Report等功能就可以获得比较准确的结果。如图1-5所示,没有了系统类所占内存的干扰,只有应用自身代码建立的对象,对于发现内存问题比较有帮助。
图1-5分离以后再次分析内存构成
对于通常的内存泄露类问题,使用以上方法后经过MAT提供的分析报告就很容易就会识别出来。在咱们以往的测试经历中,用这种方法发现了上百次的内存问题。这些内存每每是加载后忘了释放的Bitmap,临时生成的byte数组和文件缓冲区,包含Handler的Activity等等。
接下来咱们看一个真实的应用测试案例。在这个案例里,有些位图在使用完以后因为种种缘由,一直没有销毁而存在ImageLoader里,使用一段时间后ImageLoader会变得愈来愈庞大。使用上面介绍的方法去除了系统的影响后,MAT的泄露报告给出告终果,如图1-6所示,ImageLoader消耗了接近1/3的内存。
图1-6 MAT识别出来的问题
有了这样的数据,接下来就能够结合图片追踪代码,看引用到ImageLoader的代码部分哪里有问题,从而快速的修复问题。
下周咱们将带来规范测试流程及常见问题
更多精彩内容欢迎关注腾讯优测的微信公众帐号:
腾讯优测是专业的移动云测试平台,为应用、游戏、H5混合应用的研发团队提供产品质量检测与问题解决服务。不只在线上平台提供app自动化测试、云真机远程操控与调试、私有自动化测试工具XTest等多种质量检测工具,更为VIP客户配备了专家团队提供定制化综合测试解决方案。