Android 卡顿排查工具

Android基础 专栏收录该内容
2 篇文章 0 订阅

Android 卡顿排查工具

Traceview 和 systrace 都是我们比较熟悉的排查卡顿的工具,从实现上这些工具分为两个流派。

第一个流派是 instrument。获取一段时间内所有函数的调用过程,可以通过分析这段时间内的函数调用流程,再进一步分析待优化的点。

 

第二个流派是 sample。有选择性或者采用抽样的方式观察某些函数调用过程,可以通过这些有限的信息推测出流程中的可疑点,然后再继续细化分析。

 

1. Traceview

吐槽的比较多的工具。它利用 Android Runtime 函数调用的 event 事件,将函数运行的耗时和调用关系写入 trace 文件中。

Traceview 属于 instrument 类型,它可以用来查看整个过程有哪些函数调用,但是工具本身带来的性能开销过大,有时无法反映真实的情况。比如一个函数本身的耗时是 1 秒,开启 Traceview 后可能会变成 5 秒,而且这些函数的耗时变化并不是成比例放大。

 

Android sdk 自带图形化工具,用来分析函数调用过程,可以对应用程序及framework层的代码进行性能分析。

在 Android 5.0 之后,新增了startMethodTracingSampling方法,可以使用基于样本的方式进行分析,以减少分析对运行时的性能影响。新增了 sample 类型后,就需要我们在开销和信息丰富度之间做好权衡。

 

无论是哪种的 Traceview 对 release 包支持的都不太好,例如无法反混淆。其实 trace 文件的格式十分简单,之前曾经写个一个小工具,支持通过 mapping 文件反混淆 trace。

 

使用方法:

使用traceView之前,需要得到一个*.trace文件,获取方式有两种:1,DDMS中使用。

AS3.6中,(被google慢慢抛弃,不好用,但是有些地方还是可以用)需要去sdk tools 路径运行monitor.bat脚本

Start Android Device Monitor 

To start the standalone Device Monitor application, enter the following on the command line in the android-sdk/tools/ directory:

2,代码中加入trace语句,保存trace文件。

Debug.startMethodTracing("ui_performance");

Debug.stopMethodTracing();

会生成一个ui_performance.trace文件。

3,详细用法可上网搜索。

2. Nanoscope

http://github.com/uber/nanoscope

instrument 类型的性能分析工具,  Uber 开源的Nanoscope就能达到这个效果。它的实现原理是直接修改 Android 虚拟机源码,在ArtMethod执行入口和执行结束位置增加埋点代码,将所有的信息先写到内存,等到 trace 结束后才统一生成结果文件。

Nanoscope 作为基本没有性能损耗的 instrument 工具,它非常适合做启动耗时的自动化分析。

不支持debugable 的应用程序。

 

Nanoscope 生成的是符合 Chrome tracing 规范的 HTML 文件。我们可以通过脚本来实现两个功能:第一个是反混淆。通过 mapping 自动反混淆结果文件。第二个是自动化分析。传入相同的起点和终点,实现两个结果文件的 diff,自动分析差异点。

在使用过程可以明显感觉到应用不会因为开启 Nanoscope 而感到卡顿,但是 trace 结束生成结果文件这一步需要的时间比较长。另一方面它可以支持分析任意一个应用,可用于做竞品分析。

Nanoscope 生成的是符合 Chrome tracing 规范的 HTML 文件。我们可以通过脚本来实现两个功能:第一个是反混淆。通过 mapping 自动反混淆结果文件。第二个是自动化分析。传入相同的起点和终点,实现两个结果文件的 diff,自动分析差异点。

 

3. systrace

systrace 利用了 Linux 的ftrace调试工具,相当于在系统各个关键位置都添加了一些性能探针,也就是在代码里加了一些性能监控的埋点。Android 在 ftrace 的基础上封装了atrace,并增加了更多特有的探针,例如 Graphics、Activity Manager、Dalvik VM、System Server 等。

systrace 工具只能监控特定系统调用的耗时情况,所以它是属于 sample 类型,而且性能开销非常低。但是它不支持应用程序代码的耗时分析,所以在使用时有一些局限性。

那我们有没有办法在 systrace 上面自动增加应用程序的耗时分析呢?

可以通过编译时给每个函数插桩的方式来实现,也就是在重要函数的入口和出口分别增加Trace.beginSection和Trace.endSection。当然出于性能的考虑,我们会过滤大部分指令数比较少的函数,这样就实现了在 systrace 基础上增加应用程序耗时的监控。通过这样方式的好处有:

 

a,可以看到整个流程系统和应用程序的调用流程。包括系统关键线程的函数调用,例如渲染耗时、线程锁,GC 耗时等。

b, 性能损耗可以接受。由于过滤了大部分的短函数,而且没有放大 I/O,所以整个运行耗时不到原来的两倍,基本可以反映真实情况

 

systrace 生成的也是 HTML 格式的结果,我们利用跟 Nanoscope 相似方式实现对反混淆的支持。

 

 

使用方法:

1,ddms 直接使用systrace

2,使用命令行,或者脚本

Python systrace.py --time=10 -o mynewtrace.html sched gfx view vm

-h: help

-o: 输出文件

-t N, --time=N: 多少秒内的数据,默认5s,以当前时间点往后Ns

-b N, --buf-size=N:  单位为千字节,限制数据大小

-k <KFUNCS> --ktrace=<KFUNCS> :  追踪特殊方法。

-l, --list-categories: 展示需要追踪的标签。《可以从官方的systrace.html中查看标签》

-a, <APP_NAME>, --app=<APP_NAME>: 包名

--from-file=<FROM_FILE>:  创建报告的来源trace文件,用于trace文件转换。

-e<DEVICE_SERIAL>, --serial=<DEVICE_SERIAL>: 设备号

3,应用中捕获trace

Trace.beginSection(), Trace.endSection();

1, 这两个函数调用必须匹配,2,嵌套中end只能结束最近的begin。

 

4. Simpleperf

 sample 类型

http://android.googlesource.com/platform/system/extras/+/master/simpleperf/doc/README.md

它利用 CPU 的性能监控单元(PMU)提供的硬件 perf 事件。使用 Simpleperf 可以看到所有的 Native 代码的耗时,有时候一些 Android 系统库的调用对分析问题有比较大的帮助,例如加载 dex、verify class 的耗时等。

 

Simpleperf 同时封装了 systrace 的监控功能,通过 Android 几个版本的优化,现在 Simpleperf 比较友好地支持 Java 代码的性能分析。具体来说分几个阶段:第一个阶段:在 Android M 和以前,Simpleperf 不支持 Java 代码分析。第二个阶段:在 Android O 和以前,需要手动指定编译 OAT 文

件。第三个阶段:在 Android P 和以后,无需做任何事情,Simpleperf 就可以支持 Java 代码分析。

如果需要分析 Native 代码的耗时,可以选择 Simpleperf;如果想分析系统调用,可以选择 systrace;如果想分析整个程序执行流程的耗时,可以选择 Traceview 或者插桩版本的 systrace。

 

这些分析工具都支持了 Call Chart 和 Flame Chart 两种展示方式。下面我来讲讲这两种展示方式适合的场景

1. Call Chart

Call Chart 是 Traceview 和 systrace 默认使用的展示方式。它按照应用程序的函数执行顺序来展示,适合用于分析整个流程的调用。举一个最简单的例子

A 函数调用 B 函数,B 函数调用 C 函数,循环三次,就得到了下面的 Call Chart。

 

 

可以看到在这一段时间内,各个线程的具体工作,比如是否存在线程间的锁、主线程是否存在长时间的 I/O 操作、是否存在空闲等。

2. Flame Chart

Flame Chart 也就是大名鼎鼎的火焰图。它跟 Call Chart 不同的是,Flame Chart 以一个全局的视野来看待一段时间的调用分布,它就像给应用程序拍 X 光片,可以很自然地把时间和空间两个维度上的信息融合在一张图上。上面函数调用的例子,换成火焰图的展示结果如下。

 

当我们不想知道应用程序的整个调用流程,只想直观看出哪些代码路径花费的 CPU 时间较多时,火焰图就是一个非常好的选择

火焰图还可以使用在各种各样的维度,例如内存、I/O 的分析。有些内存可能非常缓慢地泄漏,通过一个内存的火焰图,我们就知道哪些路径申请的内存最多,有了火焰图我们根本不需要分析源代码,也不需要分析整个流程

  • 0
    点赞
  • 3
    评论
  • 8
    收藏
  • 打赏
    打赏
  • 扫一扫,分享海报

©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

willy8686

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值