Skip to main content

卡顿树使用教程

什么是卡顿树?

卡顿问题严重影响应用体验,也是各业务性能优化的一个重点方向。随着优化的进行,解决了一些单点的卡顿问题后,剩下的问题往往更加复杂,不容易解决。这些问题可能涉及到业务逻辑的重构,甚至需要调整交互。在制定优化策略之前,了解应用的整体卡顿状况是至关重要的,这样才能选择合适的优化目标和制定有效的策略。

建设卡顿树功能就是为了解决这个问题。通过分析足够数量的卡顿样本,卡顿树可以构建应用的卡顿全景图,帮助我们更好地了解应用的卡顿情况。这样一来,我们就能够有针对性地选择优化目标,并制定相应的优化策略。卡顿树为我们提供了全面的视角,帮助我们找到卡顿问题的根本原因,从而更好地提升应用的性能和用户体验。

一个应用往往会包含多个卡顿问题。无论是卡顿个例还是卡顿问题,都是对卡顿堆栈的一种聚合逻辑。卡顿堆栈代表了卡顿时的业务现场。

image.png

卡顿树是一种新的分析卡顿问题的方法,它将满足条件的所有卡顿样本的堆栈信息按照调用顺序聚合成一棵堆栈树。通过收集足够数量的样本并进行聚类,这棵堆栈树可以反映应用的整体卡顿情况。

如下图所示,这是两个卡顿个例聚合成的卡顿树,其中红色的数字代表节点的命中次数。由于这两个卡顿个例共抓取了14次堆栈,通过节点的命中次数,除以总抓栈次数,即可得到节点占比。

节点占比 = 节点命中次数 / 总抓栈次数

image.png

以下是Android-Demo的卡顿树演示案例。

image.png

怎么用卡顿要树?

我们通过回答几个常见问题来介绍卡顿树的使用。

1. 功能入口在哪里?

入口一:左侧菜单中,卡顿下的二级菜单,卡顿树。这个入口,默认展示应用最近上报个例的卡顿树。

image.png

入口二:卡顿问题详情,顶部「分析卡顿树」标签,点击即可查看当前卡顿问题的卡顿树。

image.png image.png

2. 分析数据有限制吗?

实时分析只支持分析,满足筛选条件的最近上报的3万个个例。如果筛选条件下,个例超过3万个,会根据上报时间,选择最近上报的3万个进行分析。

后续会推出离线计算,支持分析全量数据和对比分析,敬请期待。 image.png image.png

3. 火焰图中不同颜色的节点代表什么含义?

卡顿树的火焰图共有两种颜色,橘黄色堆栈是系统堆栈,而红色堆栈表示业务堆栈。

image.png

4. 为什么默认看到的全是业务堆栈,没有系统堆栈?

分析策略中,默认打开「忽略系统堆栈」的开关。这样设计的原因是,一般情况下,业务更关注业务堆栈导致的卡顿。用户可以调整「忽略系统堆栈」的开关,查看包含系统堆栈在内的卡顿树。

image.png

image.png

5. 节点占比的含义是什么?

节点占比 = 节点命中次数 / 总抓栈次数。如下图所示,第一个个例共抓了6次堆栈,第二个个例共抓了8次堆栈,总抓栈次数为14。

image.png

6. 为什么忽略系统堆栈会影响节点占比?

忽略系统堆栈,则是在堆栈分析前,预先对堆栈进行处理,将系统堆栈部分过滤掉,然后再构建卡顿树。构建卡顿树的原始数据发生了变化,即分母发生了变化。此时节点的意义是,卡顿期间,在所有业务堆栈中,业务节点的占比。

image.png

如下案例所示,节点「MonitorSubThreadTest.handleMessage」在全堆栈中占比30.21%。

image.png

切到「忽略系统堆栈」模式后,占比变为32.24%。

image.png

7. 火焰图和堆栈树有什么区别?

火焰图和堆栈树本质上没有什么区别,只是同一份数据的两种展示形式。火焰图比较直观,适合快速浏览整体情况。堆栈树展示信息比较全,适合深入分析。火焰图中,还提供了「查看火焰图」的入口,方便用户查看任意子树的火焰图。

image.png image.png

8. 点击节点,展示局部子树后,怎么回去?

每个节点,第一次点击时表示要查看这个节点所在的子树,再点击这个节点,则表示要查看其上级子树。如下示例所示:

  • 点击节点,点击查看局部子树。 image.png

  • 展示局部子树,选择子树根节点,点击查看。 image.png

  • 展示被点击节点的完整子树,再点击该节点。 image.png

  • 展示被点击节点的父节点的完整子树。 image.png

9. 堆栈顺序的正序和倒序分别代表什么?

正序是指堆栈的调用顺序是由上往下的,而倒序则是反过来,由下往上。 image.png

如下图所示,倒序处理时,先将堆栈倒序,然后按相同的原则构建卡顿树。

image.png

正序适合分析应用整体卡顿状况,通过节点占比来发现优化思路。如下图所示,Android-Demo这个应用主要卡顿的原因有几个,包含ListView滑动,View点击,CostTask以及MonitorSubThreadTest。通过正序分析,我们找到几个重要的优化方向。

image.png

我们继续分析叶子结点,发现Bitmap.nativeGetPixel存在多棵子树中,但是我们不能快速得知跟它相关的子树累计的占比有多少。换句话说,如果某些基础组件的执行时间较长,由于其被多个地方调用,这些耗时节点可能分散在多个子树中。在正序模式下,很难快速识别出基础组件的问题,需要对多个子树进行分析,才能得出结论。

倒序处理后,所有调用耗时方法Bitmap.nativeGetPixel的逻辑都聚合在一起了。此时,一眼就可以看到基础组件的问题。

image.png

11. 连续抓栈次数有什么作用?

连续抓栈次数是用来过滤参与构建卡顿树的堆栈。Android默认只取连续抓栈次数大于1的堆栈用来构建卡顿树,iOS默认只取连续抓栈次数大于5的堆栈用来构建卡顿树。

实时计算中,Android推荐连续抓栈阈值不小于1,iOS推荐连续抓栈阈值不小于5。

12. 怎么查看某个指定问题的卡顿树?

卡顿树提供了IssueID的筛选条件,可以通过这个筛选字段,过滤出属于指定Issue的卡顿个例来分析卡顿树。 image.png

也可以在卡顿问题详情,点击顶部的「分析卡顿树」来分析指定问题的卡顿树。 image.png

13. 还支持哪些筛选条件?

除上述筛选条件外,卡顿树还支持所有用于过滤卡顿个例的筛选条件,包含用户ID、设备ID、问题特征、监控线程、监控粒度等等,详细如下图所示: image.png