前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【穿山甲系列】找出后台偷偷耗电的元凶

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

原创
作者头像
腾讯移动品质中心TMQ
发布2017-12-29 16:10:36
1.4K0
发布2017-12-29 16:10:36
举报

作者:万宇

团队:腾讯移动品质中心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,获取更多测试干货!

版权所属,禁止转载

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景故事
  • 方案分析
  • 技术实现
    • 关键技术点一:判断耗电异常
      • 关键技术点二:上报分析
      相关产品与服务
      数据保险箱
      数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档