1.使用说明
1.1 命令用法
命令行
python systrace.py [options] [category1] [category2] ... [categoryN]
1.2 options
其中options可取值:
options | 解释 |
---|---|
-o <FILE > |
输出的目标文件 |
-t N, –time=N | 执行时间,默认5s |
-b N, –buf-size=N | buffer大小(单位kB),用于限制trace总大小,默认无上限 |
-k <KFUNCS >,–ktrace=<KFUNCS > |
追踪kernel函数,用逗号分隔 |
-a <APP_NAME >,–app=<APP_NAME > |
追踪应用包名,用逗号分隔 |
–from-file=<FROM_FILE > |
从文件中创建互动的systrace |
-e <DEVICE_SERIAL >,–serial=<DEVICE_SERIAL > |
指定设备 |
-l, –list-categories | 列举可用的tags |
1.3 category
category可取值:
category | 解释 |
---|---|
gfx | Graphics |
input | Input |
view | View System |
webview | WebView |
wm | Window Manager |
am | Activity Manager |
sm | Sync Manager |
audio | Audio |
video | Video |
camera | Camera |
hal | Hardware Modules |
app | Application |
res | Resource Loading |
dalvik | Dalvik VM |
rs | RenderScript |
bionic | Bionic C Library |
power | Power Management |
sched | CPU Scheduling |
irq | IRQ Events |
freq | CPU Frequency |
idle | CPU Idle |
disk | Disk I/O |
mmc | eMMC commands |
load | CPU Load |
sync | Synchronization |
workq | Kernel Workqueues |
memreclaim | Kernel Memory Reclaim |
regulators | Voltage and Current Regulators |
1.4 示例
例如,在systrace.py
所在目录下执行指令:
python systrace.py -b 32768 -t 5 -o mytrace.html wm gfx input view sched freq
./systrace.py -b 32768 -t 5 -o mytrace.html wm gfx input view sched freq //等价
又例如,输出全部的trace信息
python systrace.py -b 32768 -t 5 -o mytrace.html gfx input view webview wm am sm audio video camera hal app res dalvik rs bionic power sched irq freq idle disk mmc load sync workq memreclaim regulators
注:收集trace,需要提前安装python,并且一定要注意必须是python 2.x,而不是能3.x,否则可能会出现问题。另外,buffer大小不可过大,否则会出现oom异常。
python3_8不支持.png出现这种情况可以安装3.8和2.7的两个版本,然后再环境变量中将2.7的目录放在3.8之前,重启cmd运行即可。
调整python启动版本.png2.图形说明
2.1 图形化
横坐标是以时间为单位,纵坐标是以进程-线程的方式来划分,同一进程的线程为一组放在一起,可收缩/展开,如下图:
图形化.png2.2 Frames
产生的html格式的trace文件必须使用Google Chrome打开,才能正确地解析并已图标形式展现。上图中红色圈起来的,都是可以点击操作的地方,最上方是搜索栏,往下处是Alerts按钮,再往下是鼠标操作模式。
在每个app进程,都有一个Frames行,正常情况以绿色的圆点表示。当圆点颜色为黄色或者红色时,意味着这一帧超过16.6ms(即发现丢帧),这时需要通过放大那一帧进一步分析问题。对于Android 5.0(API level 21)或者更高的设备,该问题主要聚焦在UI Thread和Render Thread这两个线程当中。对于更早的版本,则所有工作在UI Thread。
frame图.png2.3 Alerts
Systrace能自动分析trace中的事件,并能自动高亮性能问题作为一个Alerts,建议调试人员下一步该怎么做。
比如对于丢帧是,点击黄色或红色的Frames圆点便会有相关的提示信息;另外,在systrace的最右上方,有一个Alerts tab可以展开,这里记录着所有的的警告提示信息。
注:本文讲到最新版的systrace,其中sdk 23,chrome版本49.0,部分功能在老版本systrace并没有。
3. 快捷操作
3.1 导航操作
导航操作 | 作用 |
---|---|
w | 放大,[+shift]速度更快 |
s | 缩小,[+shift]速度更快 |
a | 左移,[+shift]速度更快 |
d | 右移,[+shift]速度更快 |
3.2 快捷操作
常用操作 | 作用 |
---|---|
f | 放大当前选定区域 |
m | 标记当前选定区域 |
v | 高亮VSync |
g | 切换是否显示60hz的网格线 |
0 | 恢复trace到初始态,这里是数字0而非字母o |
一般操作 | 作用 |
---|---|
h | 切换是否显示详情 |
/ | 搜索关键字 |
enter | 显示搜索结果,可通过← →定位搜索结果 |
` | 显示/隐藏脚本控制台 |
? | 显示帮助功能 |
对于脚本控制台,除了能当做记事本的功能,目前还不清楚有啥功能,或许还在开发中。
3.3 模式切换
- Select mode: 双击已选定区能将所有相同的块高亮选中;(对应数字1)
- Pan mode: 拖动平移视图(对应数字2)
- Zoom mode:通过上/下拖动鼠标来实现放大/缩小功能;(对应数字3)
- Timing mode:拖动来创建或移除时间窗口线。(对应数字4)
可通过按数字1~4,用于切换鼠标模式; 另外,按住alt键,再滚动鼠标滚轮能实现放大/缩小功能。
4.使用AndroidStudio调查卡顿
4.1 选择Trace System Call
选项采集系统调用
选择TraceSystemCall.png
4.2 查看调用栈
查看调用栈.png5.总结
5.1 分析卡顿有用的信息
sched
: CPU调度的信息,非常重要;你能看到CPU在每个时间段在运行什么线程;线程调度情况,比如锁信息。
gfx
:Graphic系统的相关信息,包括SerfaceFlinger,VSYNC消息,Texture,RenderThread等;分析卡顿非常依赖这个。
view
: View绘制系统的相关信息,比如onMeasure,onLayout等;对分析卡顿比较有帮助。
am
:ActivityManager调用的相关信息;用来分析Activity的启动过程比较有效。
5.2 指令
systrace.py -t 10 -o d:/mytrace.html sched gfx view am -a com.example.myapplication
5.3 不同category使用场景
测试列表滑动, 桌面滑动等流畅性问题
gfx input view若在上面的基础上 还需要分析HWUI
gfx input view hwui测试app启动或者进入某个界面的速度
gfx input view am wm res怀疑有GC或者是IO导致的卡顿
gfx input view dalvik disk怀疑有power相关的问题
gfx input view res am wm power
5.4 分析卡顿原因
当前系统线程状态判断卡顿原因.png点击frame图,查看线程状态推断卡顿原因,不同颜色代表不同线程状态:
-
绿色:运行中
作用: 查看Running状态的线程,查看其运行的时间,与竞品做对比,分析快或者慢的原因是否频率不够,问题可能性:-
是否跑在了小核上
-
是否在Running 与Runnable之间切换? 为什么?
-
是否在Running 与Sleep之间切换? 为什么?
-
-
蓝色:
作用:Runnable状态的线程持续时间越长,则表示cpu调度越忙,没有及时处理这个任务-
是否后台有太多的任务在跑
-
是否频率太低
-
被限制某个具体的cpuset cpu很满?
-
此时Running状态的线程是哪个? 为什么?
-
- 白色:
作用: 一般都是在等待事情驱动,在互斥锁上被阻塞
- 橘色 不可中断的睡眠态? 一般都是线程在IO上被阻塞 或者等待磁盘操作 IO操作很慢
大量的橘色出现 表明 低内存状态
-
紫色: 可中断的睡眠态
- 线程在另一个内核上被阻塞,有可能是正常的,也有可能是不正常的
从上图可以看出每一帧之间存在大量白色色条,说明在等待绘制。因此需要怀疑为什么会等待绘制,例如正在网络或者本地加载数据,三大绘制流程耗时过多?
5.5 Linux 进程状态
D 无法中断的休眠状态 (IO 进程)
R 正在可运行队列中的
S 休眠状态
T 停止
W 内存交换
X 死掉的进程
Z 僵尸进程
5.6 线程优先级
Process.setThreadPriority()/ Thread
thread_priority_display = -4
thread_priority_foreground = -2
thread_priority_default = 0
thread_priority_background = 10
thread_priority_lowest = 19
5.7 调查步骤
-
使用原生设置的
Profile GPU Rendering(GPU渲染模式分析)
功能,大概看一下柱状图哪些地方丢帧严重 -
使用Systrace查看丢帧发生的时刻线程状态,缩小调查范围,参考4.4怀疑项。
-
使用Android Studio查看调用栈,详细分析代码耗时/block原因。
网友评论