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最初设计用于SurfaceFlingerPerformance,因此不带任何参数启动时,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的火焰图的颜色不是没有意义的。