0%

Android Trace实战

做App启动优化,Trace是优化过程中必不可少的工具。Android中提供了两种trace分析工具,method trace是抓取线程中代码的执行栈和耗时;systrace 是抓取app使用过程中cpu、线程和锁阻塞等信息。

1 method trace

1.1 trace 文件介绍

通过method trace 抓取线程中执行的方法栈和方法耗时。如图,通过分析主线程的方法调用,解决主线程耗时逻辑。
image.png

1.2 trace文件的抓取

trace文件的抓取有两种方式。推荐第二种。
1) Android Studio的Profile模式。
这种方式只需要在开启profile模式,点击cpu,进入cpu页面后点击record。
image.png

对于启动阶段的method trace需要通过配置才能开启。
image.png

image.png

image.png

这种方式优缺点

  • 优点: 不用写代码耦合。
  • 缺点:trace文件抓取需要通过Profile模式,Profile模式必须在debug模式下才能进行,而debug和release模式在性能上差异较大,会让问题分析有较大误差。

2) 通过代码抓取
在app启动的时候startMethodTracingSampling,首页加载完成后stopMethodTracing,然后会生成trace文件,将手机中的trace文件导出到电脑上,通过profile窗口打开。

1
2
Debug.startMethodTracingSampling(traceName, 0, sampleInterval);
Debug.stopMethodTracing();

image.png

这种方式优缺点

  • 优点: trace文件debug和release模式都可以抓取,release模式抓取的文件分析耗时更加准确。
  • 缺点:需要在工程中添加代码,但是代码量较少。

2 systrace

Systrace 是 Android4.1 中新增的性能数据采样和分析工具。它可帮助开发者收集 Android 关键子系统(如 SurfaceFlinger/SystemServer/Kernel/Input/Display 等 Framework 部分关键模块、服务,View系统等)的运行信息,从而帮助开发者更直观的分析系统瓶颈,改进性能。

Systrace 的功能包括跟踪系统的 I/O 操作、内核工作队列、CPU 负载以及 Android 各个子系统的运行状况等。
关于 Systrace 的官方介绍和使用可以看这里:Systrace

2.1 systrace的使用

  1. 安装Python ,并将其包含在系统环境变量的path中。
  2. 查找Systrace脚本,存储路径如下:android-sdk/platform-tools/systrace/
  3. 代码中增加Trace.beginSection(mName) Trace.endSection()
  4. 执行命令python systrace.py -o mynewtrace.html -a 包名 sched freq idle am wm gfx view input。更多命令参数可参考官方文档。

2.2 systrace文件分析

chrome中输入chrome://tracing/,将生产的trace拖到浏览器中。
image.png
systrace基础和高阶知识 https://androidperformance.com/2019/05/28/Android-Systrace-About/

这里我们关注每个线程上方的线条。

  • 绿色 : 运行中
  • 蓝色 : 可运行
  • 白色 : 休眠中

2.3 systrace实战-解决依赖关系

关注白色线条部分。点击下方的monitor contention字样,然后查看下方consle内,可以看到具体的锁等待,具体阻塞在哪个线程方法,找到这个线程,然后在通过method trace中搜索阻塞方法的关键字,就可以找到依赖关系,通过编排任务顺序、解决锁等待使得任务高效执行。
image.png

2.4 systrace实战-提高重要任务执行效率

找出关注的重要任务tag,关注蓝色线条部分。
Runnable 状态的线程状态持续时间越长,则表示 cpu 的调度越忙,没有及时处理到这个任务:

  • 是否后台有太多的任务在跑?
  • 没有及时处理是因为频率太低?
  • 此时 Running 的任务是什么?为什么?

优化手段比如启动优化过程中的将任务打散,任务多阶段分批执行。

2.5 systrace总结

其实通过systrace解决好上述两点基本已经优化大部分问题了,在极致的优化可以看下上面贴的外链文章具体看看,收益也很大。

3 trace view

trace view 是chrome上面提供的开发工具,Trace Viewer 有一套自己的 Trace Event Format,只要文件遵循这个格式,就可以被展示。
通过这点,在启动过程中,将启动过程中的信息记录json,可回溯排查启动慢的问题。

trace对应的 json 文件内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"name": "myName", // 事件名,会展示在 timeline 上
"cat": "category,list", // 事件分类,类似 Tag,但 UI 上不支持选择 Tag
"ph": "B", // phase,后面着重会讲到
"ts": 12345, // 事件发生时的时间戳,以微秒表示
"pid": 123, // 进程名
"tid": 456, // 线程名
"args": { // 额外参数,当选中某个 event 后,会在底部的面板展示
"someArg": 1,
"anotherArg": {
"value": "my value"
}
}

其中最重要的是 ph,最常用的组合是 B 和 E,分别表示 Begin 和 End,有了这两个信息,Trace Viewer 就能在 timeline 上找到起止点,将它绘制出来。也可以简化为 X,然后加上 dur 表示 duration

1
2
3
4
5
[ {"name": "出方案", "ph": "X", "pid": "Main", "tid": "工作", "ts": 0, "dur": 28800000000},
{"name": "看电影", "ph": "X", "pid": "Main", "tid": "休闲", "ts": 28800000000, "dur": 360000000},
{"name": "写代码", "ph": "X", "pid": "Main", "tid": "工作", "ts": 32400000000, "dur": 360000000},
{"name": "遛狗", "ph": "X", "pid": "Main", "tid": "休闲", "ts": 36000000000, "dur": 180000000},
]

image.png

但颜色看起来有点随机,能不能自定义呢,可以的,这时就要用到 cname 这个参数: “cname”: “good”

具体可查看 https://blog.csdn.net/u011331731/article/details/108354605