火焰图
Cloud Profiler 使用火焰图显示性能剖析数据。与树和图表不同,火焰图通过紧凑、可读的格式表示大量信息,有效地利用屏幕空间。
为了介绍火焰图,本页面演示了如何将树转换为火焰图,并总结了火焰图的主要特点。
创建火焰图
如需根据树来创建火焰图,请完成下图中所示的步骤:
从树中移除指示函数调用的箭头。
用帧替换每个树节点。
帧的形状为矩形,所有帧的高度相同。 对于本页面中的示例,帧中指明的函数使用的总计 CPU 时间决定了帧的宽度。
每个函数的伪代码如下表所述。在函数执行期间执行的 CPU 密集型工作定义了自身 CPU 时间:
函数伪代码 自身 CPU 时间
(秒)总计 CPU 时间
(秒)func main(): foo1() foo2() // CPU intensive work // for 2 seconds
2 4 + 3 + 2 = 9 func foo1(): bar() // CPU intensive work // for 1.5 seconds
1.5 2.5 + 1.5 = 4 func foo2(): bar() // CPU intensive work // for 0.5 seconds
0.5 2.5 + 0.5 = 3 func bar(): // CPU intensive work // for 2.5 seconds
2.5 2.5 下一步是移除帧之间的垂直空白,并将帧向左边对齐,同时保持调用序列。 (可选)您可以定义一个配色方案,并根据定义为帧着色。 例如,您可以按照软件包、总计 CPU 时间、自身 CPU 时间或其他计量单位对帧进行着色。
移除多余的空白并按照自身 CPU 时间对帧着色后,火焰图现在如下所示:
请注意,
foo1
和foo2
的调用堆栈已保留,即使以foo2
开头的调用堆栈现位于foo1
的帧旁边。
总结
这个简单的示例说明了以下几个方面:
- 火焰图是树的紧凑表示形式,通过从顶部向下跟踪帧,您可以重新创建调用堆栈。
- 帧指明一个函数,帧的宽度是该函数的总计 CPU 时间的相对大小。
在本示例中,因为
foo2
的总计 CPU 时间是main
的总计 CPU 时间的三分之一,所以foo2
的帧宽度是main
的帧宽度的三分之一。 - 帧下方的空白区域的宽度是帧中指明函数的自身 CPU 时间的相对大小。
例如,在帧
foo1
下方,1.5 个单位为空,2.5 个单位被bar
占用。因此,foo1
的自身 CPU 时间是其总 CPU 时间的 37.5%,即 1.5 秒。 当您跟踪调用堆栈时,帧的宽度会减小,因为被调用者的总计 CPU 时间不可能超过调用者的总计 CPU 时间。这种行为是形成火焰形状的原因。
在本示例中,
foo1
调用bar
,foo1
的总计 CPU 时间定义为bar
的总计 CPU 时间加上foo1
的自身 CPU 时间。因此,bar
的总计 CPU 时间不可能超过foo1
的总计 CPU 时间。