主持人:时间有限,可以把问题发在群里,大家私下沟通。谢谢!最后一位是来自阿里的,话题是讲APP深度性测试

尚进:大家好!我是来自移动测试平台的尚进,今天主要是来说深度性能测试的,有点标题党,其实就是普通的性能测试。
我们做测试平台的,有渲染的热烈的竞争市场。因为我们现在每个APP上市场的竞品都非常多。行为挑剔的用,还有良莠不齐的设备。因为我们是做测试的,所以我们平台上会维护大量的不同配置的手机,这个时候你会发现平时大家用的都是性能比较好的,山寨机是承受不了的。

先讲怎么做性能测试,包括APM,还有线上线下的。我们今天主要讲发布前的线下的测试,在制定机型上拿到固定的性能case获取性能数据。我们常用的指标包括启动时长、CPU、内存。很多性能问题不需要放在线上解决,在线下解决,所以我们今天主要是发现线下的问题。

首先我们有内部的在线监控,这是我们的另外一个服务,它可能会抓取CPU的基础启动时长和内存占用的基础数据,今天来讲一下深度性能测试给大家带来的更为细致的分析。
包括内存方面有内存泄露、内存溢出等。还有大家非常重视的UI流畅度,跟用户体验非常相关的,包括界面的切换和调帧流畅度的分析和右面渲染的分析。最后是启动分析和严苛模式。

内存泄露这一块儿网上的资料非常多,给大家讲一下GC ROOT,我们去持续地持有这样的对象的时候,并且持有方不会被释放的时候把它成为GC ROOT,包括静态的定位还有浏览。还有Instance of Application。

讲一下很简单的例子,极核里面会持有的对象。是刚才讲的静态类别去持有,它是被静态对象给持有了,所以东西不会释放,导致我们内存不断地增长。大家遇到比较少的包括我们给很多客户做测试的时候发现一个问题,安卓上的消息循环是有延时发送的机制,会持有处理器的应用。所以这个时候有延迟5分钟发送消息,如果这些消息一直没有被处理导致消息泄露。这是我们可以拿到的表表,这里可以看到标明了是这样的数据。因为会做管理,这个时候一不小心会发生内存泄露。

内存溢出包括虚拟机的内存限制,现在安卓手机的配置越来越高了,内存限制已经上升到了几百兆,2012年的时候手机比较低端,内存线可能是32兆是比较典型的,那个时候会经常出现OM,但现在出现的越来越少了伴随着应用越来越复杂还是偶然地会出现。包括安卓会提供了一些非常有效的分析工具,包括DDMS、还有刚刚推出的新的内存分析工具,大家可以去看一下。WeakReference可以解决大部分的隐私和内存泄露的问题,大家平时可以多使用一下。

接下来讲UI流畅度的问题,这个图已经烂大街了。第一帧数据数据是正常的周期,第二帧数据结构比较复杂会导致渲染过程长会跟第三帧画面同步在一起,引入垂直同步之后可以避免大量的画面撕裂的问题,但是我们还是没有解决这个问题。刚才前面几位都提到了掉帧是不可避免的,目前来讲是这样的。所以我们有必要去监控掉帧。这个时候网上大量的说话是通过绘制机制,推算出当前的流畅度,这是业界比较常用的。这个时候是有侵入性的。我们其实在这个基础上做了更多的工作,帮大家更多地定位,怎么定位流畅度发生时刻,发生的是什么样的状况。所以我们推出了视频流动,会在测试过程中对手机进行录屏,得到视频。包括最后会监控每一个Activity的切换,我们知道安卓的UI通过三期循环不换地抓新的数据新的消息实现UI的更新我们有必要去监控UI每一个消息的处理时长,如果处理时间长的话可以报出来。

这是最后产生的数据,对这样一个应用来说,它可能在绝大部分时刻都是掉帧率比较严重的情况,实际大家用的情况都是比较流畅,因为我们操作可能比较慢,但在测试平台上用工具可以覆盖在更多的Activity上。平台切换的时候会发现应用出现了大量的掉帧。
中间的是它的流畅度,下面的蓝色点是代表每个时刻的掉帧情况,下面有Activity的切换,在这个时刻我们给Activity发送切换,同时对比发现流畅度是比较低的,这个时候会发现在Activity切换的时候确实出现了大量的掉帧。因为我们是做测试工具的,所以会反馈给开发修复这样的问题。

还有卡顿的监测,刚才讲到了Activity有一个处理消息的线程,我们去监测消息分发的处理时长,发现有异常处理的时候会报出来,消息卡顿了4.0秒,但实际中可能不太会出现,这是我们自己做的demo不一样的卡顿。我们的平台大多数出现的卡顿1到2秒的是比较常见的,应用会出现5到8处或者是更多的卡顿,这是大家可以关注的一个点。具体怎么优化呢?不要去同步堵塞消息循环。
还有影响流畅度的就是过度绘制。安卓官方定位上面的几个色块,蓝色浅蓝色是代表画面的绘制,绿色代表每一个画面被绘制了两次,浅红色代表绘制了三次,深红色代表了四次。可能大家做安卓开发的都会比较了解。

这里是我们平台上的客户案例,这一块儿可能会出现了比较严重,包括这一块儿,我们会发现界面上绝大多数都严重地过度绘制,可能直接导致最终掉帧的出现。在整个安卓绘制过程中在CPU做界面元素去分析,包括它会生成一个短节奏给GPU的时候花费了太长的时间。包括GPU在绘制的时候有更多的元素。

何减轻过度绘制呢?网上都有建议,简单讲几点,去除无用多余的背景设置,减轻每一个复杂度,利用安卓的动态加载界面。

下面还有今天想着重想的就是安卓的启动分析。谷歌官方提供的ADB会返回启动时间,这个时间有可能是不太准的,因为它的原理是真正画面静止时候的时长,这个时间一般会出现大概1秒左右的延迟。所以我们有必要去分析一下Activity在启动的时候都做了什么事。

首先讲一下安卓的系统进程,最早是Init进程,通过Init进程去孵化出其他的进程,比较特殊的是引用了Zygote进程,它会孵化出所有的Applications和Services。我们每一个应用都是通过采购和进程去孵化出来的。再一个Activity应用启动的过程中流程就是StartActivity,因为安卓是一个单线活动的,Activity是唯一的只有一个,分屏的业务都是定制的,我们只考虑单一Activity的情况。会把当前界面上的Activity给Pass掉,如果我们没有启动影响的话会调用Applications去启动。这个时候会有Activity Svrvice去管理所有的东西。

安卓的多人按纽弹下来的东西是每一个Activity的活动过程。Activity Stack是安卓命令的入口,它会在里面调用,系统会给你分配新的进程。最后才到Application thread。安卓做了很多的事情,从Activity启动到画面又会发生更多的事情,包括对应用相关的可能就是Applicationattach。为什么要把这个单独拎出来说?会导致二进制增大很多,这个时候会出现一个情况,会出现多个ds文件的情况。如果你用谷歌官方的那一套加载ds的工具的话会在applicationattach里面卡很久,当然这个时候可以用很多的第三方的硬加载或者是动态加载的东西,阿里又出了一个方案。所以这个时候要提一下。application.onCreate大家都非常熟悉,绝大多数操作都是在这里面实现的。

冷启动是说系统还没有Application的时候需要冷启动,这个时候会创建新的应用程序的进程再去启动Activity。热启动是说系统里面已经有了应用的进程,这时候启动相应的Activity就可以了。

这是安卓提供的官方分析工具叫TraceView,在很早期就可以推出了。上面第一排数据是每一个方法情况,右边有一连串的彩色的线,黑色的是频繁的调用导致频繁的切换。可以看到主线程是一直在占用CPU,出现了大量的方法调用。中间粉红色那一段持续了很长时间,如果点击它拿到下面的信息,包括它每个方法调用了它,它调用了哪些函数都可以看到。

右边是INZL,包括了它的子函数的执行时间的时间。它实际占用的时间是右边,后面还有不包括子函数的调用时间,是它自己的运行时间。我们可以看到这个函数自己并没有占用多少时间,它绝大部分时间都是自己占用的,自己占用了97.8%的运行时间,所以我们这个时候在优化上会针对这样的函数去优化它的逻辑。其实可以看到其他的时候并没有调用太多的其他函数,所以定位其实是这个函数出现问题。

刚刚那个图有很多不关注的东西,包括很多是系统函数我们并不关心,我们关心由于我们自己操作带来的问题,因为系统函数没办法去改变。这是我们平台上某一个客户的APP启动的整个流程的分析。灰色的代表系统方法,蓝色代表的是APP自己的方法,蓝色的占用了整个流程的接近一半的时间。右边浅黄色时间比较短,可能只是一个开机界面,所以时间非常短。

我们后来可以看到紫红色占用了三分之一的时间,这个时候就是应用的主Activity出现了。为什么会占用这么久呢?大家都知道这是给界面加元素加布局,可以看到它的布局是有大量的优化空间,因为它绝大多数时间都是花在了布局的解析和绘制上。后面也做了一点操作,但这个不重要。大家发现这个APP最大的问题是有大量的第三方的SDK,大量都是在Application里面产生的,还有它有了大量的时间拖的比较久。

这也是我们做的更优更简洁的数据。可以看到我刚才有讲到的非常关键的函数,比如说Activity的 great,我们会给出关键的耗时排名,初始化的时候我们主要关注两方面,这里没有出现问题说明这个应用还是比较简单,没有用到多个DS,或者说它做了优化我们没有检测到。代码混淆这一块儿目前还是没有办法解决的。

可以看到Activity的启动,启动了三个,第一个Activity可能是刚才说的界面,比较简单没有什么问题。重点关注一下第二个Activity。所以整个流程下来会对应用的启动过程做比较深入的分析,包括它每一个方法的调用都是可追诉的,这个时候用户主要是面向测试。主要是方便定位问题,所以这是我们这一块儿的启动分析。

还有一个很好用的工具就是安卓提供的StrictMode,就是严苛模式,它会去监测安卓应用在主线程进行耗时操作,比较典型的就是读写操作合网络请求之类的。当应用中有没有关掉的Closeable的查询或者是Activity泄露它也会报,还是会监测比较多的事情,应用在主线程当中进行网络请求,或者是某些耗时方法。大家回去都可以在自己的应用启动的时候加这样一个模式,看一下到底有哪些问题。这是我们平台上给客户检测到的在主线程进行的磁盘读写,中间大量的信息都是跟Activity无关的,可能都是系统策略。
今天最后一个讲的比较快,耽误大家时间了,谢谢!

主持人:有问题吗?

尚进:因为我们这个角度主要是从测试的角度出发的。

主持人:我看今天报名来的也有不同的小伙伴。

提问:其实我没有什么问题,我想具体了解一下你这个测试平台,我们私下可以了解吗?不是特别清楚及
尚进:我们是做真机测试的,平台上会购买主流的平台覆盖到80%到90%的机型,都会放在我们平台上自动化,包括动力探索。
提问:我想了解你最后说的严苛模式,刚才没有特别。
尚进:我们可以私下。

提问:服务是免费的吗?
尚进:我们有免费的服务也有付费的服务,看你们需求。
提问:客服是怎么支持?
尚进:有专门的达疑邮箱。
提问:在线客服有吗?
尚进:有。
提问:需要介入你们的SDK做?
尚进:我们主打的是非侵入式的APP测试。
提问:直接把APP塞进入?
尚进:对,大家讲塞SDK会有数据侵入的问题,我们这个不会,大家可以放心大胆地用。

提问:我想问一下你刚刚提到启动文件的问题,现在冷启动应用多还是热启动应用多?
尚进:对大多数用户来讲可能是热启动比较多,对付费的可能会面临比较多的冷启动,看大家APP的应用场景。
提问:根据场景来分的?
尚进:对。APP就像微信一样。