当前位置:Java -> CPU性能分析 - 火焰图

CPU性能分析 - 火焰图

对于任何分布式大规模软件应用程序来说,控制成本是最重要的方面之一。随着业务的增长,核心软件应用程序的成本可能会变得非常高。

对于基于云的弹性分布式系统,可以通过监视和优化应用程序的CPU来管理成本,如果系统的横向扩展和纵向缩减受CPU使用率阈值的控制。一种方法是生成应用程序的flame graph(火焰图),以了解CPU的热点。

根据我的经验,通过分析和减轻flame graph中的CPU热点,我已经成功将大型分布式系统的成本降低了10%至15%。对于更大的系统,即使降低1%的成本也可能会导致巨大的成本节约。

火焰图

火焰图是应用程序控制流的可视化。它显示了应用程序调用栈中的函数序列,以及这些代码段所使用的CPU百分比。

某个例程或调用栈的CPU百分比是根据该例程的样本数与分析期间的总样本数的比较来计算的。

理解火焰图

下面是火焰图的一个示例可视化。一个常见的误解是将x轴视为时间的推移。实际上,x轴是按字母顺序排列的函数调用或调用栈,y轴是调用栈深度。

sample graph

在示例图中,主要的调用栈是Main.main,它调用了Main.FunctionA、SampleA.FunctionA和SampleB.FunctionA,但调用顺序并非一致,这些调用是按字母顺序排列的。

当鼠标悬停在特定的例程上时,会显示该例程的总样本数和CPU使用率。以下显示了SampleA.functionC例程的样本数为858个,使用率为30.58%。

CPU profile

现在,如果某个例程的执行不应该像火焰图中显示的那样久,就应该检查是否存在可能的优化。

一些浪费的活动可能是不必要的轮询、过多的对象层、冗余检查以及不必要的对象反序列化和序列化。

对于大规模应用程序或使用现有框架的应用程序,火焰图可能会变得非常密集。在这种情况下,最好是在图中搜索特定的例程,而不是逐个查看每个调用栈。例如下面是一个用于示例Java基于reactor的gRPC服务的火焰图。

a flame graph for a sample Java reactor-based gRPC service

通过搜索特定例程来定位其用法会更容易。在这种情况下,例程greet()被搜索。

routine greet() is searched

生成

有许多工具可以生成火焰图。本文所使用的工具是async-profiler。它是一个简单的低开销的分析器,还可以防止由于安全点抽样而导致的问题,并且下载和使用都很简单。

以下是使用async-profiler生成30秒时间窗口的火焰图的命令。

asprof -d 30 -f cpu_profile.html <process_id>


结论

CPU性能分析是识别CPU热点的重要方面,而火焰图是分析CPU热点的好方法。

如果做得正确,CPU性能分析可以显著降低大型弹性应用程序的成本。根据我的经验,通过火焰图识别CPU热点,我已成功降低了大型应用程序10-15%的成本。

如有任何疑问或需要针对您的使用情况提供指导,请随时联系我。

推荐阅读: 2022全球程序员薪资排行:中国倒数,美国写Go最挣钱

本文链接: CPU性能分析 - 火焰图