【穿山甲系列】找出后台偷偷耗电的元凶

作者:万宇

团队:腾讯移动品质中心TMQ

背景故事

先来看一个浏览器用户反馈。

如图所示,在浏览器用户反馈中,耗电一直是头部问题之一,用户对于电量是非常敏感的,特别是那种类似“我明明就没用,怎么还在耗电?”的后台耗电问题,更容易引起用户的抱怨。

遇到这些情况,项目组和测试组都比较无奈。我们明明一直都有做耗电测试,本地的耗电监控也一直跑的很溜。但是线上仍然有这些问题,应该怎么办呢?

所以,我们需要一种新的耗电监控的方案,来解决线上用户反馈的耗电问题。

方案分析

对于线上用户耗电的监控,我们需要解决两个问题。

1、线上用户不同于本地测试,不可能随时把手机拿到进行调试,我们如何在app端获取足够的信息,以方便后期的调试分析?

2、线上用户数量庞大,不像本地测试才个位数的机器,这么多用户,手工分析太耗时,我们如何进行自动化分析?

先考察一下现有的耗电监控的方案:

测试方法一:BatteryHistorian(https://github.com/google/battery-historian

Battery Historian是Google推出的专用来分析Android App耗电的工具,通过简单的操作便可在网页中生成比较详细的图表,展示手机上各模块电量消耗情况。我们主要用Battery Historian来做定期的例行测试,并以邮件的形式同步测试结果。

BatteryHistorian报表

测试方法二:Method Profiling

针对常见的用户场景,在浏览器切后台时通过DDMS Method Profiling抓取后台执行的所有任务。Method Profiling一般是用来分析性能问题的,它会记录每一个线程、每一个方法的耗时,也正是利用了这一点,我们可以清楚地看到浏览器在切后台后都做了哪些事情。

对比两种方案, 最终我们选择了基于后台Method Profiling方案,因为这个方案有两个优点。

1、MethodProfiling在用户手机上容易执行, 调用一个函数抓trace即可, 而Battery Historian需要执行shell命令。

2、MethodProfiling有更加丰富的函数执行信息, 而Battery Historian只能够获取一些系统事件。

技术实现

线上监控别于本地测试,本地测试可以简单粗暴,但在用户的手机上,必须考虑方案对用户的影响。Method Profiling生成的Trace文件相对来说是比较大的,最大可能有几十兆,我们不可以把所有用户的Trace文件都上报上来。

另外,监控本身可能导致耗电,例如我们首先排除的方案——用一个例行线程不断记录当前所有线程,所以在设计方案时需要将监控本身的影响降到最低。

几轮讨论后,我们最终采用了这样的思路——首先监控是否存在后台耗电现象,当判断为后台耗电现象后开始Method Profiling并通过穿山甲上报。

这样我们上报的都是经过筛选的有问题的场景,一方面减轻了后台数据存储的压力,另一方面也相当于做了过滤,减轻后台分析的工作量。

最终线上耗电监控的具体方案如下:

1、切后台时,记录当前进程对CPU占用的时间片;

2、切后台一段时间后,再获取进程对CPU占用的时间片,如果发现耗电异常,开始Method Profiling;

3、MethodProfiling进行一段时间后停止,上报trace文件到穿山甲后台;

4、穿山甲后台对上报的trace文件进行分析和处理,并自动提BUG单。

关键技术点一:判断耗电异常

APP耗电的产生主要是对CPU产生了占用,我们通过获取浏览器占用CPU时间片的数据来判断是否异常耗电。在Linux系统中,可以通过/proc/<pid>/stat查看进程对CPU的占用数据。

打印的第14~17个参数依次表示(单位:jiffies):

114242 utime,任务在用户态运行的时间

20692 stime,任务在核心态运行的时间

6 cutime,累计的任务的所有的waited-for进程曾经在用户态运行的时间

2 cstime,累计的任务的所有的waited-for进程曾经在核心态运行的时间

Jiffies是Linux内核中代表时间的变量。系统中定义了一个常数HZ,代表每秒种最小时间间隔的数目,jiffies的单位就是1/HZ。每个CPU时间片,jiffies都要加1。进程的CPU时间片占用就是用户态+系统态的jiffies,进程占用的jiffies越大,对CPU的占用越多。

114242 + 20692+ 6 + 2 = 134942 (jiffies)

在浏览器切后台时,记录当前进程占用的jiffies,当切后台达到设定时间后(10分钟),再次获取当前占用的jiffies,当两次差值超过设定阀值时(400jiffies),判定为发生了后台耗电事件。阈值设定参考了手机厂商后台耗电的评判标准。

关键技术点二:上报分析

当判定后台耗电后,开始抓取Trace,时长1分钟,Trace结束上报数据到后台。

正式版用户数庞大,我们上报的trace文件相对来说比较大,如果正式版做监控上报数据量会相当庞大, 目前资源无法支持。当存在耗电场景时,抽取一部分用户应该也是可以监控到的,所以我们选取一部分内测版的用户做监控和上报耗电异常。另外为了避免消耗用户流量,我们只会在WiFi环境下上报数据。

当存在耗电问题时,上报上来的trace文件会比较多,我们不可能每一个上报都做人工分析处理,所以需要一个程序来进行自动化的分析。

对trace数据文件的分析参考了TraceView源代码,主要是对Metho Profiling文件格式的解析。从Method Profiling数据中我们可以得出当次上报有多少个线程在运行,每个线程里都调用了哪些方法,以及每个方法的调用栈、耗时等。

有了方法的耗时, 调用栈等信息, 是不是就可以确定问题了?

一个耗时长的调用栈, 是不是就是耗电的元凶呢?

答案:并不是!

根据历史经验, 一个孤立的调用栈, 就算它比较耗时,但很多时候并不是耗电问题的元凶. 真正的耗电原因, 常常是一些定时任务, 浏览器切后台以后本应该停止, 但这些任务还一直在执行, 导致耗电量大, 而这些调用栈, 具有下面一些特征:

(1)多次被调用;

(2)调用具有规律性;

(3)调用比较耗时。

所以,我们从trace文件中,对每个调用栈,分别计算下面3个指标。

1)调用次数,记为count;

2)调用时间间隔的方差, 记为diviation;

3)运行耗时, 记为cost。

针对每一个调用栈, 我们给出一个评分:

Score = cost * count / diviation

分数越大的调用栈,越可能是耗电问题。同时,我们把类似的栈进行合并,上报次数越多的调用栈,影响面越广。最终,我们根据排序,将Top50的调用栈标记为疑似耗电问题,自动提交Bug。

Trace源文件

最终Bug信息:

分析结果:

实施效果

以下是从引入线上电量监控以来的相关数据统计。

关注微信公众号:腾讯移动品质中心TMQ,获取更多测试干货!

版权所属,禁止转载

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏coolblog.xyz技术专栏

I/O模型简述

最近在学习 Java NIO 方面的知识,为了加深理解。特地去看了 Unix/Linux I/O 方面的知识,并写了一些代码进行验证。在本文接下来的一章中,我将...

3557
来自专栏WeTest质量开放平台团队的专栏

浅谈服务器性能测试的全生命周期——从测试、结果分析到优化策略

服务器性能测试是一项非常重要而且必要的工作,本文是作者Micheal在对服务器进行性能测试的过程中不断摸索出来的一些实用策略,通过定位问题,分析原因以及解决问题...

1383
来自专栏NetCore

从三个方面提高网站的链接广泛度

从三个方面提高网站的链接广泛度      网站的链接广泛度(Link Popularity)在搜索引擎排名中的作用已得到广泛的认同和重视。实际上,即使...

1725

比较服务网格体系结构

如果你正在围绕微服务构建您的软件和团队,那么你应该正在寻找更快迭代和灵活扩展的方法。服务网格可以帮助你在保持(或增强)可见性和控制的同时实现这一点。在这篇博客中...

2556
来自专栏张戈的专栏

教你如何查看Linux的CPU负载

记得博主以前被问到 CPU 负载如何才算高的时候,出过一次糗,具体就不记录了。。。在网上找了一篇比较详细的 Linux 下的 CPU 负载算法教程,科普一下。不...

5016
来自专栏即时通讯技术

移动端IM中大规模群消息的推送如何保证效率、实时性?

众所周之,群聊是移动端IM的服务端技术难点所在,难在哪?大量的群聊消息,是一条条推给群内成员还是可以使用什么样的优化策略?试想一个2000人大群,一条消息的发出...

921
来自专栏Python小白进阶之旅

学会了爬虫,然后我一不小心就统治了整个Python吧

2048
来自专栏腾讯移动品质中心TMQ的专栏

后台性能测试不可不知的二三事

某月黑风高之夜,某打车平台上线了一大波(G+)优惠活动,众人纷纷下单。于是乎,该打车平台使用的智能提示服务扛不住直接趴窝了(如下图)。事后,负责智能提示服务开发...

3737
来自专栏杨建荣的学习笔记

数据库无响应问题的紧急处理和分析 (r10笔记第42天)

黄金周里处理了一起紧急的问题,在外面幸亏有同事帮忙协助,等我赶回家去,赶紧继续处理。 首先问题是在晚饭时间左右开始发生,但是过了没多久又恢复了,所以这个问题暂时...

32312
来自专栏java一日一条

Linux 新手容易犯的 7 个错误

改变操作系统对于任何人来说都是迈出的一大步,特别是当许多用户不确定操作系统究竟如何的时候,尤其如此。

681

扫码关注云+社区