移动性能测试 安卓应用性能调试和优化经验分享

安卓绿色联盟 · 2019年02月20日 · 1178 次阅读

安卓绿色联盟应用性能标准主要基于主观体验、资源消耗和应用质量三个方面进行制定。

1、主观体验

主观体验主要是对应用启动时间和界面帧率制定标准,要求应用在视觉上足够流畅。其中应用启动时间又分为冷启动时间和热启动时间。

安卓绿色联盟性能标准要求,应用冷启动时间需小于 1000ms,热启动时间需小于 500ms;普通应用帧率应大于 55fps,游戏视频帧率应大于 25fps。

2、资源消耗

资源消耗主要是要求应用不能占用过高的内存和 CPU。

安卓绿色联盟性能标准要求应用前台内存占用应小于 500M,后台内存占用应小于 400M;在 CPU 占用方面要求应用在后台灭屏 5 分钟后,CPU 占用不超过 2%。

3、应用质量

应用质量主要是对应用过度绘制和内存泄露的情况作出要求,规定应用不能存在过度绘制和内存泄露。

安卓绿色联盟性能标准要求应用界面任意像素点不存在 4x 的绘制的情况, 3x 绘制的区域不能超过界面面积的 1/3,在 Strict Mode 中不允许有红框闪烁。

性能调试方法

在了解性能调试方法之前,我们可以先通过下图了解安卓应用性能与系统之间的关系。一个应用从应用绘制到最终显示在 LCD 上经历了一个漫长的路径,在任何一个阶段出现延时都会导致界面上的卡顿。

image

1、Strict Mode

Strict Mode 意思为严格模式,是 Android 提供的一种运行时检测机制,一般用来检测在主线程发生的耗时动作,比如 IO 读写、数据库操作、复杂算法等。在手机设置开发者选项把 Strict Mode 打开,就可以在界面上把它打开了。

严格模式主要有 2 个策略,一个是线程策略,即 ThreadPolicy,主要检测主线程中的一些耗时操作;另一个是虚拟机策略,即 VmPolicy,主要检测一些对象的泄漏。

两大策略检测的内容和开启方法可以依据下图中的说明进行使用。

image

严格模式有三种惩罚模式:应用崩溃、弹窗警告和打印日志。在性能测试中,我们可以通过 APPLogcat 抓取 Strict Mode 的日志,同时利用代码启用 Strict Mode,配合我们所需要的策略和惩罚,就可以及时定位应用的违规细节,并及时进行性能优化。

当我们碰到违规的行为时,该如何进行治理呢?建议将文件操作放到工作线程去完成,如果在主线程上提及操作,建议使用 Apply 和 Commit 去完成。如果存在对象未关闭的情况,可以通过对应的 StackTrace 进行关闭。

2、OverDraw DeBugger

Overdraw 是指屏幕上的某个像素在同一帧的时间内被绘制了多次,这个工具使用色块来代表不同数量的过度绘制,我们可以使用这个工具来定位由过度绘制引起的用户界面卡顿问题。

在开发者选项中选择开启 Debug GPU Overdraw 选项,即可在安卓设备上将过度绘制问题可视化。

image

左图为正常模式下显示的视图,右图为开启 GPU Overdraw 后显示的视图

3、Profile GPU Rendering

ProfileGPU Rendering 工具以滚动直方图的形式直观地显示渲染界面窗口帧所花费的相对时间(以每帧 16 毫秒的速度作为对比基准)。这个工具同样也是在安卓设备的开发者选项中开启。每个管线的高度表示时间,管线中各个彩色区段代表不同含义。

下表介绍了使用运行 Android 6.0 及更高版本的设备时分析器中不同竖条区段的含义。

image

4、Android Profiler

Android Profiler 是一个 Android Studio 集成的应用性能分析器,可以实时查看 CPU、Memory 和 Network 的动态情况。以下重点介绍 CPU Profiler:

CPU Profiler 可帮助您实时检查应用的 CPU 使用率和线程 Activity,并记录函数跟踪,方便大家优化和调试应用代码。

当打开 CPU Profiler 时,它将显示应用的 CPU 使用率和线程 Activity。

image

CPU Profiler 可以选择不同的标签,并对应用线程进行跟踪。如:

(1)Flame Chart 标签会提供一个倒置的调用图表,汇总相同的调用堆栈,收集调用顺序完全一致的函数,并在火焰图中用一个较长的横条表示它们。

(2)Top Down 标签能够提供每个函数调用上所花费的 CPU 时间。Self 表示函数调用在执行自己的代码上所花的时间;Children 表示函数调用子方法所花费的时间;Total 表示 Self 和 Children 时间的总和。

5、Systrace

Systrace 是我们分析性能最常用的工具之一,它可以分析整机系统性能及动态场景的性能问题。

Systrace 允许您在系统级别收集和检查设备上运行的所有进程的计时信息。它将来自 Android 内核的数据(例如 CPU 调度程序,磁盘活动和应用程序线程)组合起来,以生成 HTML 报告。

image

上图左部是 Systrace 的界面,我们可以通过右边的代码抓取 Systrace,观察进程的执行时间。在输入抓取命令时,时间参数一般选择 5 到 10 秒,因为时间过短可能会抓不到想要的数据,时间过长则可能抓取失败。

一般我们通过 Chrome 浏览器查看生成的 trace 文件,也可以通过 DDMS 图形界面去抓取 Systrace。

image

拿到一个 Systrace 时主要考察哪些因素?首先看一下 CPU 的频率,找到对应的进程或者线程,查看相关信息;同时还要观察 GPU 的频率、Surface Flinger 还有绘图的 Buffer 状态等。

当应用发生卡顿时,我们可以通过 Systrace 进行分析。在生成的 trace 文件中,找到主线程 UI,每一帧都会标记一个带有 F 的圆形。当原型为绿色时,代表页面流畅,而黄色和红色则存在超时,我们可以点击去查看具体存在什么问题。

性能案例分析

案例 1:界面滑动卡顿

image

从图中可以看到,这是一个手动滑动事件,当 deliverInput 事件发生后,第一帧就发生了卡顿。从 systrace 看 UI thread 执行 draw 的时间相当耗时导致丢帧卡顿,而且大部分时间都在做 decodeBitmap,共耗时 99.045ms。这时,我们打开 applog 发现,有 StrictMode 相关的错误提示,从中可以定位到耗时函数。

image

从上图我们看出有一个网络访问违规,大概可以推测应用在从网络上下载了一个数据流,数据流里可能包含了一些图形,通过 decodeBitmap 把它解析出来展示在 UI 界面中。正产情况下,我们应该把网络访问放在工作线程里面去处理,将数据下载完了之后再放到主线程中去展示,避免这种问题的发生。

案例 2:Strict Mode 错误提示

image

从上图 Strict Mode 的日志可以看出:StrictMode policy violation 耗时 2 秒左右。通过最下行蓝色的 log,可以知道应用是在某一个目录里面寻找一个文件,判断文件是否存在。

面对这种问题,我们应该把 IO 操作放到工作线程。正常情况下 IO 的发生非常快,但是在系统繁忙时,IO 放在主线程会产生较大的问题,因为它要等别的程序读写完成之后,才会下发,产生超时。

案例 3:GPU 调用不当导致的卡顿问题

image

这是一个 GPU 的例子,上图主要问题是 GPU 使用了太长时间处理应用传过来的 buffer,例子中 Surfaceflinger 使用 GPU 做了图像叠加,说明图层比较多。使用 GPU 做叠加主要会产生功耗和唤醒耗时的问题。大家在做界面设计的时候,尽量不要使用 GPU 进行叠加。在上面的例子中,GPU 叠加之后,导致了大概 15ms 左右的延时,因为 GPU 操作完成以后还需要交给 Surfaceflinger 把图像显示到屏幕上。

案例 4:CPU 调用不当导致的界面滑动卡顿问题

image

可以通过上图的红色条块了解 messageloop RunTask 信息,红色条块上的蓝色 bar,表示线程在 CPU 上的状态。蓝色表示这个线程处于等待 CPU 调度的状态,可见等待超过 8ms 的时间,是正常调度周期好几倍。导致这种情况发生的原因有两个:CPU 负载过大或 CPU 调度出现了问题。在上图中我们可以看出,CPU0 和 CPU1 使用率 100%,但是 CPU2 和 CPU3 是 offline 的状态,说明系统出现问题,导致 CPU2 和 CPU3 未能唤醒,帮助完成系统任务。

性能优化建议

1、避免内存泄露

在应用开发过程中,首先要避免内存泄露的问题,内存泄露是一种比较严重的性能问题,在安卓绿色联盟应用性能标准中也要求应用不允许发生内存泄露。

下图是常见的内存泄露防范方法和内存泄露检测工具。

image

2、避免不良设计或程序算法导致 CPU 占有率持续偏高

主要业务处理分散到不同线程,便于后续利用多核处理器的并行处理能力,避免一核累死,7 核围观;
使用 top 命令观察应用线程的 CPU 占有率,找出高负载的进程进行分析,并针对优化。

3、避免 OnXXX 回调函数中进行耗时操作,避免主线程卡顿

Android 系统中正常情况下所有 onXXX 类函数均运行在主线程中。

image

在上图中,我们可以看到两帧中间有一个因为接收广播处理导致的 158ms 的卡顿。在这些函数中,我们应该避免网络通信操作、文件读写操作、数据库数据改动的操作、图形处理、文本分析等操作,将这些工作尽可能的移到工作线程中去,从而避免主线程卡顿。

4、合理使用系统资源

合理使用系统资源主要指的是软资源。下图是对广播资源调用的一些建议。

image

关注安卓绿色联盟公众号,回复关键词 “23”,获取 PPT。

暂无回复。
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册