[转帖]火焰上的JVM--用火焰图分析性能

火焰,jvm,分析,性能 · 浏览次数 : 0

小编点评

## 火焰图简介 火焰图是一种用于分析应用程序性能的方法,它可以帮助你快速识别热代码路径。它使用堆栈样本进行分析,并通过图表显示代码执行的流程。 ## 火焰图创建方法 1. **获取火焰图工具**: - 使用 Maven构建应用程序:`mvn install FlameGraphTool` - 使用其他方式获取,例如从 GitHub 上下载 2. **执行应用程序**: - 在命令行中运行应用程序,并将 `-XX:+PreserveFramePointer` 参数传递给 `java` 命令。 3. **获取堆栈信息**: - 使用 `-XX:+DebugnonSafepoint` 参数启动分析,并将 `100` 个秒的时间指定给 `perf-map-agent` 命令。 4. **创建火焰图**: - 运行 `perf-java-record-stack` 命令,并将 `-i` 和 `-o` 参数传递给该命令。 5. **导出火焰图**: - 运行 `FlameGraph` 命令,并将 `-color=java --hash` 参数传递给该命令。 ## 示例代码 ``` # 创建火焰图的命令 java -XX:+PreserveFramePointer -cp Cpu-0.0.1-SNAPSHOT.jar de.codecentric.training.javaprofiling.cpu.PrimeFinderRunner 1000000 1 1 # 获取堆栈信息 export PERF_RECORD_SECONDS=30 perf-map-agent/bin/perf-java-record-stack <PID> # 创建火焰图 /FlameGraph/stackcollapse-perf.pl /tmp/out-<PID>.stacks | tee /tmp/out-<PID>.collapsed | /FlameGraph/flamegraph.pl --color=java --hash > /tmp/flamegraph.svg ``` ## 相关链接 - FlameGraph 官方文档: - `FlameGraph` 文档 - `Stackcollapse` 文档 - 使用 `FlameGraph` 生成火焰图的教程: - 教程 - 使用 `Stackcollapse` 生成火焰图的示例代码: - 代码

正文

https://zhuanlan.zhihu.com/p/374861737

 

目前有几种工具可用于分析应用程序的性能并显示结果。传统上,这些结果要么以某种表格形式显示,要么以平面形式显示,要么以树视图的形式显示。火焰图是比较新的,并采取一个新的角度来显示结果。
此外,可以在不同的级别上生成火焰图;工具连接到JVM,但也可以在(Linux/MacOS)OS级别上连接。

在这篇文章中,我希望给你一些关于火焰图是什么,如何读取它们,以及创建它们可用的工具的一些想法。

什么是火焰图?
火焰图是Brendan Gregg发明的一种显示轮廓结果的方法。或者,正如他所说:

火焰图是抽样堆栈痕迹的可视化,它允许快速识别热代码路径.

下面您将看到一个来自SpringBoot演示应用程序的示例火焰图。

 

 

火焰图一般是根据取样剖面仪的结果生成的。这些将创建堆栈样本,然后可以转换/折叠以获得生成火焰图的正确格式。然后,该图形由BrendanGregg的FlameGraphTool生成,这是一个简单的Perl脚本,将输出一个SVG映像。
SVG图片的好处在于它可以被搜索和过滤(不幸的是,在这篇博客文章中是不可能的),这使得它非常容易遍历。另外,生成火焰图的输入是一个简单的文本文件,可以很容易地被黑客攻击以添加/过滤信息!

火焰图将提供以下信息:

  • Y-轴/高度:显示堆栈深度。
  • X轴/宽度:表示在一个方法中花费了多少时间(样本数)。
  • 颜色:取决于配置,例如突出Java、C++、内核方法

值得注意的是X轴!=时间的流逝。堆栈帧按字母顺序从左到右排序。所以只看宽度,而不是轴上的位置。

将其与下面的JProfiler树视图进行比较,在该视图中,概述丢失的速度要快得多。

 

 

 

但是,在查看分析结果时,请确保您知道正在查看的是什么。某些分析器,例如,遭受‘安全点抽样偏差’(因此,我们将使用诚实的Profiler稍后)。类似地,在使用插装时,由于额外的开销,这可能会导致结果混乱,因此不建议使用。

需要开始

火焰图真正好的地方是,您可以只为Java生成它们,也可以在OS级别(Linux和OSX)生成它们,以获得更低级别的信息。以前,由于信息丢失,系统分析器无法填充整个Java堆栈。由于JDK 8更新60 Build 19(也包括JDK 9),框架指针信息通过以下选项固定-XX:+保护框架。稍后,我将展示如何生成JVM仅火焰图以及OS级火焰图。

生成Java专用火焰图

对于这个例子,我们将使用同事构建的一个非常简单的应用程序来进行一些CPU分析:轮廓仪Schulung
。虽然这不会以任何方式产生花哨的结果,但运行起来很简单,只运行很短的时间,并且使JVM和OS级分析结果之间的差异非常明显。可以使用Maven构建应用程序。

为了生成Java火焰图,我们将使用诚实的Profiler。除了不受SafePoint偏见的困扰外,分析器还包括转换堆栈信息的代码,以便为FlameGraphTool的处理做好准备(尽管这有点隐藏)。

第一步是在执行应用程序时包括诚实的Profiler代理。完整的命令如下所示:

java -agentpath:/honest-profiler/liblagent.so=interval=7,logPath=/tmp/log.hpl -cp Cpu-0.0.1-SNAPSHOT.jar de.codecentric.training.javaprofiling.cpu.PrimeFinderRunner 1000000 1 1

申请可立即启动。完成后,这将输出/tmp/log.hpl包含原始堆栈信息的文件。
这需要转换为折叠堆栈数据是这样的:

java -cp /honest-profiler/honest-profiler.jar com.insightfullogic.honest_profiler.ports.console.FlameGraphDumperApplication /tmp/log.hpl /tmp/log.folded

根据这些折叠的堆栈信息,我们现在可以创建火焰图:

/FlameGraph/flamegraph.pl /tmp/log.folded > /tmp/flamegraph-java.svg

如果一切顺利,就会产生以下图表:

 

 

 

 

您可能会得到一个稍微不同的结果,因为小代码正在内联。这可以通过使用以下选项来解决-XX:InlineSmallCode=100为了防止内联,除了非常小的代码块。或使用其他(首选)选项:-XX:+解锁诊断VMOptions-XX:+DebugnonSafepoint.

正如你在图中所看到的,也有一些“未知”AGCT.未知的Java样本是可见的。无法映射这些信息来捕获堆栈信息,VisualVM等工具根本不会显示它们。在接下来的步骤中,它们将在LinuxPerf中变得可见。

生成Linux火焰图

接下来是有趣的内容,我们将使用LinuxPERF事件在操作系统级别上进行分析。重要的是要注意的是PERF命令与Java进程分开运行,因此我们首先需要启动Java,然后启动分析。此外,我们需要分别抓取堆栈信息,以填补空白。在JVM执行内联、类加载、垃圾收集等操作时,请确保分析一个“稳定”的JVM,否则就会读取陈旧的数据,并且某些堆栈帧可能无法得到映射。

为了让我们的生活更轻松,PERF-地图代理工具包括一些用于运行PERF命令,同时获取堆栈映射。甚至还有一个脚本来额外创建火焰图,但是为了清晰起见,我们将手动完成这个步骤。

首先,在启用框架指针信息的情况下启动Java应用程序:

java -XX:+PreserveFramePointer -cp Cpu-0.0.1-SNAPSHOT.jar de.codecentric.training.javaprofiling.cpu.PrimeFinderRunner 1000000 1 1

搜索正在运行的进程的PID(PS aux\grep java)。然后启动分析30秒,然后自动获取堆栈映射信息:

export PERF_RECORD_SECONDS=30
perf-map-agent/bin/perf-java-record-stack <PID>

默认情况下,这将在/tmp。我们还需要PERF事件然而,需要提取的信息如下:

sudo perf script -i /tmp/perf-<PID>.data > /tmp/out-<PID>.stacks

最后,我们可以折叠堆栈信息并一次创建火焰图:

/FlameGraph/stackcollapse-perf.pl /tmp/out-<PID>.stacks | tee /tmp/out-<PID>.collapsed | /FlameGraph/flamegraph.pl --color=java --hash > /tmp/flamegraph.svg

现在您应该看到以下输出:

 

 

 

 

正如您在创建的映像中所看到的,除了单个正在运行的线程之外,还可以看到更多的信息。这些都是JVM内部运行的操作,比如垃圾收集。在SpringBoot应用程序的第一个示例中,可以找到更多的堆栈。

我邀请你自己安装这个工具并试一试。看看创建了什么样的火焰图,以及如何导航它们以获取所有信息。请参阅下面的一些链接,以使您开始或获得更多的深入信息。

与[转帖]火焰上的JVM--用火焰图分析性能相似的内容: