写点什么

Facebook 是如何收集其 Android 应用性能数据的

  • 2015-11-02
  • 本文字数:2068 字

    阅读完需:约 7 分钟

Facebook 一直致力于不断提高 Android 应用的运行速度。虽然他们内部已经有类似 CTScan 这样的性能跟踪系统,但 Android 生态系统的多样性使他们无法在实验室中测试每一种可能。因此,他们希望通过遥测技术从人们真实使用的 Android 手机中收集性能信息来补充测试数据。近日,Facebook 工程师 Delyan Kratunov撰文介绍了他们收集 Android 应用远程性能检测数据的方法。

很长一段时间以来,遥测技术都仅限于费力地插入代码,标识动作的起点和终点。这种方法有诸多弊端:

  • 开发者插入的检测点限制了遥测数据的详细程度,并导致这种方法只能检测可以预见的性能影响;
  • Android 应用的多线程特点以及用户交互的高度异步特点导致很难彻底检测代码;
  • 代码的快速变化会导致已有的检测标记出现“位衰减”。

同时,Delyan 还指出,他们也不希望使用下面这两种方法:

  • 使用 Android 内置的性能检测方法:Dalvik 和 ART 都提供了可以从“Debug”类调用的、方法级的性能分析器。这些方法可以编程触发,输出结果保存在开发人员指定的文件中。但是他们发现,startMethodTracing 方法开销很大。更糟糕的是,在某些 Android 版本中,该方法会禁用 Dalvik 的 JIT 编译器,进一步降低应用性能。总之,该工具会扭曲检测数据。
  • 大幅增加手工插入的检测点:手动插入性能检测点非常耗时且容易出错。工程师的时间不应该花费在可以自动化的事情上。而且,在一个不断变化的代码库中,确保这类检测点的正确性需要做大量的工作。

他们所采用的方法,灵感来自于该领域先前的研究,核心是一个基于规则的字节码重写器(基于 ASM 库)。该重写器可以匹配代码位置,然后插入或操作代码。就是说,在 Java 代码经 javac 编译成 Java 虚拟机字节码之后,但是在传递给 dx 转换成 Dalvik VM 格式之前,它会介入修改 JVM 字节码。

作为构建系统的一部分,该字节码重写器会在 Android 应用的全部 Java 字节码上运行,执行少数几个简单的转换,产生大量发生过重写的代码位置。例如,下面的规则将在特定方法的入口和出口处插入代码:

复制代码
new EntryExitRule.Builder()
.setMatcherConfiguration(
subclassesOf(
getObjectType("android/app/Activity")
).withMethods(
getMethod("void onCreate(android.os.Bundle)"),
getMethod("void onRestart()"),
getMethod("void onStart()"),
getMethod("void onResume()"),
getMethod("void onPause()"),
getMethod("void onStop()"),
getMethod("void onDestroy()")))
.setDetourType(LOG_UTILS_TYPE)
.setDetourMethodEntry(LOG_METHOD_ACTIVITY_START)
.setDetourMethodExit(LOG_METHOD_ACTIVITY_END)
.setCategory(Categories.LIFECYCLE)
.build()

在运行时,这些方法会在日志中记录一个或多个检测事件,并且,这些事件可以组合到一个单独的跟踪文件中。他们的检测粒度是框架调用和回调层。就是说,检测应用如何同 Android 框架交互以及框架反过来如何调用应用。这非常有用,因为应用组件不同生命周期之间的交互对运行时性能有重大影响。而且,由于检测点插入是自动完成的,所以无需担心代码变化会影响检测点。

在字节码中插入检测点还有一个好处,就是让他们能够透明地处理异步跟踪。也就是说,他们可以在线程之间自动传递足够的上下文信息。这样,他们就能将逻辑控制流串连起来。例如,下面的规则是检测Handler API 的:

复制代码
RedirectionRule.builder()
.setMatcherConfiguration(
subclassesOf(
getObjectType("android/os/Handler")
).withMethods(
getMethod("boolean post(Runnable)"),
getMethod("boolean postAtFrontOfQueue(Runnable)"),
getMethod("boolean postAtTime(Runnable, Object, long)"),
getMethod("boolean postAtTime(Runnable, long)"),
getMethod("boolean postDelayed(Runnable, long)"),
getMethod("void removeCallbacks(Runnable)")))
.setDetourClass("com/facebook/tools/dextr/runtime/detour/HandlerDetour")
.setCategory(Categories.ASYNC)
.build()
{1}

虽然有无数种在线程之间切换控制的方法,但实际上,一个很小的规则集合就可以覆盖应用中大多数异步代码。总的来说,这种跨线程跟踪能力让他们对应用执行流程有了更深入的了解,可以暴露出一些难以捉摸的性能缺陷,如调度延迟和不必要的异步跳转。

此外,在实现该方法的过程中,他们还遇到了其它一些需要克服的问题。比如,仅使用基本数据类型。当字节码重写器操作应用代码时,它会在每个代码位置插入一个唯一标识。在应用构建时,它会生成一个标识与代码位置的映射。在运行时,他们只记录 32 位的整型标识,然后在服务器端转换成代码位置。这样,事件大小就可以固定,而且非常小。同时,这也缩小了跟踪文件,减少了运行时开销。此处仅举一例,更多信息请查看原文


感谢郭蕾对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群InfoQ 好读者)。

2015-11-02 18:003787
用户头像

发布了 1008 篇内容, 共 449.1 次阅读, 收获喜欢 346 次。

关注

评论

发布
暂无评论
发现更多内容

再迎巅峰!阿里爆款分布式小册开源5天Github已73K

冉然学Java

架构 分布式 微服务 java; 编程、

开源一夏 | 自己画一块ESP32-C3 的开发板(PCB到手)

矜辰所致

开源 硬件设计 8月月更 ESP32-C3

零基础培训学习大数据课程

小谷哥

【有奖征文 第13期】至简致远,“云”响世界,大胆秀出你的华为云技术主张,高额激励等你拿

科技怪咖

面试官:Redis 大 key 要如何处理?

Java永远的神

Java 数据库 redis 程序员 面试

开源一夏 | Spring事务传播机制

六月的雨在InfoQ

开源 Spring事务 8月月更

JavaScript 里三个点 ...,可不是省略号啊···

华为云开发者联盟

JavaScript 前端 运算符 函数

什么是低代码开发?大家都真的看好低代码开发吗?

优秀

低代码开发

有了国产 DevOps 工具 ,还怕数字化转型成本高?

飞算JavaAI开发助手

基于微信小程序的幼儿园招生报名系统开发笔记

CC同学

一文读懂字节跳动“埋点验证平台”

字节跳动数据平台

字节跳动 数据治理 埋点治理 数据研发 埋点验证

如何选择ui设计机构

小谷哥

面向云时代的龙蜥操作系统 是 CentOS 替代的最佳选择

OpenAnolis小助手

龙蜥操作系统 开放原子全球开源峰会 OpenAnolis 分论坛 CentOS 停服 CentOS 迁移最佳选择

电商秒杀系统架构设计

泋清

#架构训练营

LED显示屏在会议室如何应用

Dylan

LED显示屏 led显示屏厂家

携手数字创新 共筑国产生态 7月份AntDB与5款产品完成互认证

亚信AntDB数据库

AntDB 国产数据库 AISWare AIDB

秋招冲刺版!奉上[Java一线大厂高岗面试题解析合集]

冉然学Java

面试 面试题 大厂 java; 秋招

湖北钠斯网络数字藏品交易系统

开源直播系统源码

NFT 数字藏品

Java面试项目推荐,15个项目吃透两个offer拿到手软

冉然学Java

offer java; 技术栈 MAll java项目实战分享

赶紧收藏!!!我直接上瘾!百万人都在学的Docker

指剑

签约计划第三季 8月月更

前端培训机构课程怎么样

小谷哥

基于DevCloud进行黑白棋实时对战游戏开发实践【华为云至简致远】

科技怪咖

大数据培训课程哪个好呢?

小谷哥

兆骑科创创业赛事活动举办平台,投融资对接,线上直播路演

兆骑科创凤阁

兆骑科创赛事服务平台对接,海内外高层次人才引进

兆骑科创凤阁

原来如此!谷歌架构师10年呕心沥血汇成的《23种设计模式》,这才是正解

冉然学Java

架构 23种设计模式 java; 编程、

干货:从零设计高并发架构

C++后台开发

高并发 架构师 C/C++后台开发 C/C++开发 高并发架构

优雅地实时检测和更新 Web 应用

领创集团Advance Intelligence Group

Web Web应用

「Gitee篇」如何用Git平台账号登录建木CI

Jianmu

git 开源 DevOps 低代码 gitee

web前端培训班哪个好选择

小谷哥

Facebook是如何收集其Android应用性能数据的_Meta_谢丽_InfoQ精选文章