Inferno:为Android原生应用生成火焰图——Flamegraph generator for pure native app
简介
本文介绍Inferno
工具。Inferno基于SimplePerf
,用于为Android native应用生成火焰图(Flame graph
)——如SurfaceFlinger
。As we all known,Android中常用Perfetto
或Profiler
的method trace来生成应用层的火焰图,但是它们对native进程束手无策。Inferno
正是为此而生,可以将Inferno
看成是支持native app的Profiler.MethodTracer。
Inferno
最初被设计和制造出来是用于分析和优化SurfaceFlinger
的性能的,目前能针对任何native app工作,以及非native app的native部分。正如同Profiler,Inferno
生成native code的flame graph,并同样的生成可视化的HTML。
下图展示Inferno
对SurfaceFlinger
生成的火焰图的示例。
原理
Inferno
的原理和结构都非常简单,因为不论是执行method trace的组件还是生成火焰图的组件都是调用已有的优秀的工具。
Inferno
利用SimplePerf
(SimplePerf
是Android基于Linux的perf
实现的)实现对Process的method trace,包含方法跟踪、栈帧展开、堆栈回溯等实现method trace的核心功能均调用SimplePerf
实现。SimplePerf
产生的perf.data
会被Inferno
从设备中拉取并分析——主要是合并堆栈、计算耗时占比。
然后,Inferno
像大多数性能工具一样通过火焰图组件生成统计数据。只要将数据喂入,数据的生成过程并不要求额外精力投入。
因此,Inferno
结构非常简单。Simple,but not easy。
火焰图的作者是性能工具大师Brendan Greggkai设计并开发的。他是享誉全球的大能。Wiki
使用
Inferno
基于Simpleperf
开发,与Simpleperf
位于同一个目录。system/extras/simpleperf/scripts/inferno
- Default:抓取SurfaceFlinger前文阐述过,
1
./inferno.py
Inferno
最初设计用于SurfaceFlinger
Performance,因此不带任何参数启动时,Inferno
会抓取SurfaceFlinger
的method trace(实际上是Simpleperf
抓的)然后生成火焰图到HTML。
不带参数时默认抓取SF: Default option is: "-np surfaceflinger -f 6000 -t 10".
上文提到method trace实质上由Simpleperf
处理,对应参数如下。其中-p指定pid,-f为method sample的频率(method trace普遍有两种实现,一个是trace,一个是sample。Trace类似与在函数进入和退出都打点记录,Sample类似于每隔一小段时间就使用暂停分析栈帧、栈展开/栈回溯分析的方式——采样),-f指定的就是采样频率。–duration指定本次采集10秒。
1 | /data/local/tmp/simpleperf record -o /data/local/tmp/perf.data --call-graph fp -f 6000 --duration 10 -p 451 |
- 参数
- -du dwarf_unwinding,使用dwarf来实现栈回溯。缺省情况下是使用fp来实现回溯的
- -e events,使用发生了events来触发采样(sample),缺省情况下是sample
- -f fr,指定采样频率
- -np NATIVE_PROGRAM,指定目标进程且目标进程必须是native进程
- -p App,指定目标进程且目标进程必须是Android应用进程
- –pid PID,等同于np,仅形式是pid
- –record_file 指定Simpleperf的记录文件,(Simpleperf)缺省为perf.data
- –system_wide 抓整个系统的,而不是单个进程;这个参数可以把系统里面所有进程都生成火焰图(实际上,就是给
Simpleperf
传递-a参数,要求Simpleperf
全局抓) - -t 抓多久
- -o 指定输出HTML的路径
- –one-flamegraph 缺省时,目标进程的所有线程是单独分开、各自生成各自的火焰图。该选项将所有线程都合并进一张火焰图
- –kallsyms 指定kernel的符号方便解析
- –symfs 指定进程的符号方便解析
- –show_art_frames 采样ART的栈帧
- -c {hot,dso,legacy}, –color {hot,dso,legacy};指定生成的图标样式。三个样式差异在于,hot是最适合performance的、耗时多少决定了长度的模式;legacy记录调用的函数,没有热力分析功能;dso记录callsite
发现性能瓶颈(bottleneck):寻高原期定CPU cost——find CPU cost by looking for plateaus
- 按照火焰图的基本功能,可以直接找在火焰尖的较长的平台,它们基本都很有可能是性能热点。
火焰图就是看从下往上看的哪个函数占据的宽度最大,只要有“平顶”,就表示该函数可能存在性能问题
- 颜色:颜色为橙色或者红色表示性能消耗较大。注意!通常来说,原生的常规的火焰图的颜色不代表任何意义,它的颜色是为了好区分每一行而随机选择的,不具备任何意义。不过
Inferno
做了些修改,颜色越深,如红色和橙色,表示消耗越大。Inferno
的火焰图的颜色不是没有意义的。