网站首页 > java教程 正文
一、原理和基本流程
Systrace是android性能调试优化的常用工具,它可以收集进程的活动信息,如界面布局、UI渲染、binder通信等;也可以收集内核信息,如cpu调度、IO活动、中断等;这些信息会统一时间轴,在Chrome浏览器中显示出来,非常方便工程师性能调试、优化卡顿等工作。
简易的流程图如下,systrace是基于ftrace实现的,而ftrace 是 Linux 内核中的调试跟踪机制。
首先systrace指定抓取trace的类别等参数,然后触发手机端的/system/bin/atrace 开启对应文件节点的信息记录,接着atrace会读取 ftrace 的缓存,生成只包含ftrace信息的atrace_raw。
Systrace会进一步收集系统的ps、task等信息,这些信息是为了协助解析atrace_raw中的ftrace信息,比如ps信息可以得到进程的名称,而不是难记的pid号。处理后的ftrace信息将和systrace目录下的prefix.html、systrace_trace_viewer.html、suffix.html整合为一体,成为单个的html文件。
当浏览systrace信息时,Chrome浏览器借助systrace解析器(通过chrome://tracing访问),解析上面生成的trace.html文件,把其中原始的ftrace信息分门别类,再按照时间轴聚合排列,绘制出不同色块,简洁可观的显示在html页面上。
二、具体实现
Systrace是怎么把系统多种多样的信息都整合进ftrace中的呢?请看下图:
Systrace抓取的trace数据,总体上可以分为两类,一类是Java和Native在用户层发生的函数调用,一类是内核态的事件信息。
用户层的函数调用,其实最终事件记录都是同一个文件节点/sys/kernel/debug/tracing/trace_marker。
此节点允许用户层写入字符串,ftrace会记录该写入操作时的时间戳,当用户在上层调用不同函数时,写入不同的调用信息,比如函数进入和退出分别写入,那么ftrace就可以记录跟踪函数的运行时间。
atrace在处理用户层的多种trace类别时,仅仅是激活不同的TAG,如用户选择了Input类别,则激活ATRACE_TAG_INPUT;选中Graphics则激活ATRACE_TAG_GRAPHICS,记录调用的流程都是一样的,最终都是记录到trace_marker。
内核态的事件信息,则不是统一的,需要激活各自对应的事件节点,让ftrace记录下不同事件的tracepoint。例如激活进程调度信息记录,需要激活如下相关节点:
events/sched/sched_switch/enable
events/sched/sched_wakeup/enable
内核在运行时,根据节点的使能状态,会往ftrace缓冲中打点记录事件。
最终,上述两类事件记录都汇集到同一缓冲中,然后atrace工具会回读抓取,保存下来就是原始的systrace信息。
三、显示定制信息
Systrace的参数设置和使用方法,网络上内容已经不胜枚举,就不再累述。下面讲解一下较少阐述的显示定制信息功能。
一般情况下,默认的systrace各种trace类别已经涵盖了系统的各个方面,足够工程师分析调试了。但某些特定情况下,工程师需要增加自定义的trace类别,并同样集成到systrace中。比如工程师需要观察到内核各个run queue的队列深度,那么他应该怎么做呢?
1.新加定制的trace类别
既然原有的systrace trace不能满足,需要新增一项。可以去frameworks/native/cmds/atrace/atrace.cpp中增加一类category, 如
2.内核增加对应的tracepoint
Systrace是基于ftrace的,那么上面的类别需要在内核中增加对应节点。
在新建的sched_rq_running event中实现输出新增的trace类别的信息,通过上面的1、2两个步骤,在抓取systrace时选中新建类别kernel_runqueue, 则抓取的trace.html将包含sched_rq_running的信息。
假设新的信息如下:
3.显示出sched_rq_running的信息
如果sched_rq_running.html 在 chrome里面打开,我们并没能发现自定义的任何信息显示出来。这个是由于默认的chrome://tracing 解析器并不知道如何解析sched_rq_running的信息。
Systrace能够解析显示出进程调度的sched_wakeup、sched_switch等信息,那是因为chrome://tracing 解析器知道如何解析进程调度信息,如下面格式的内容。
但是并不知道如何解析自定义的sched_rq_running信息。
这时候,我们就需要寻根溯源了,我们先找到systrace的生母,谷歌开源项目https://chromium.googlesource.com/catapult。
正是catapult生成了systrace及其解析器的工具。在catapult中,谷歌采用javascript实现了一个跨平台的trace解析工具,我们可以参考tracing/tracing/extras/importer/linux_perf目录下的各种解析器,比如sched_parser.html是用于解析进程调度信息的,power_parser是用于解析cpu频率等信息的,学以致用生成自己定制的sched_rq_running_parser.html。
Catapult的各种解析器,可以理解为先按照trace的类型分类处理,然后加入各个时段的采样值。
如tracing/tracing/extras/importer/linux_perf/power_parser.html
实现了如何解析出cpu频率信息:
<idle>-0 (-----) [001] d.Hb 948.300084: cpu_frequency: state=1344000 cpu_id=2
1)power_parser.html注册了cpu_frequency信息由函数cpuFrequencyEvent处理
2) cpuFrequencyEvent分解cpu_frequency信息
3) 把cpu频率采样值加入Clock Frequency信息栏
在我们加入额外的sched_rq_running_parser.html解析器之后,需要使用tracing/tracing_build/generate_about_tracing_contents.py重新生成about_tracing.html和tracing.js(这里需要改名,使之和about_tracing.html中的script脚本名称相同)。
然后使用about_tracing.html作为新的systrace解析器,代替默认的chrome://tracing,这时再把sched_rq_running.html放进来解析,我们就终于可以看到自定义的systrace信息了。
参考文献
1、android源代码
2、catapult源代码
添加极客助手微信,加入技术交流群
- 上一篇: 简单的java实现滑动时间窗口限流算法
- 下一篇: 分布式ID生成——雪花算法 分布式id生成器
猜你喜欢
- 2024-12-24 Java 8 新增6接口:Optional、Consumer等
- 2024-12-24 java小知识-纳秒 纳秒是什么
- 2024-12-24 弃用 Java 8,Apache Kafka 3.0 发布
- 2024-12-24 Sharding Sphere-JDBC从入门到实战,一顿饭的时间让你学懂
- 2024-12-24 Java虚拟机之 XX:+UseGCLogFileRotation 解析
- 2024-12-24 阿里Java三面:分布式延时任务方案解析,万字长文一篇点通你
- 2024-12-24 拯救Java应用:Arthas监控术,让你事半功倍
- 2024-12-24 java+uniapp实现微信JSSDK扫码功能
- 2024-12-24 filebeat收集K8S日志,写入自动创建的索引
- 2024-12-24 Java 动态调试技术原理及实践 java动态配置
你 发表评论:
欢迎- 04-27微服务部署架构设计详解(图文全面总结)
- 04-27Java微服务架构选型与对比:一场技术流派的巅峰对决
- 04-27微服务架构下Java的最佳实践
- 04-27Java微服务架构选型:优雅拆分与高效整合
- 04-27微服务架构下的Java代码拆分策略:像拼图一样构建系统
- 04-27微服务架构下的Java最佳实践
- 04-27微服务架构下Java的挑战与机遇
- 04-27微服务架构下Java事务管理的艺术
- 最近发表
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)