[转帖]人工智能 Java混合模式火焰图

人工智能,java,混合,模式,火焰 · 浏览次数 : 0

小编点评

**生成 Java 混合模式火焰图的脚本** ```bash #!/bin/bash # 设置环境变量 SLEEP_SECONDS=$1 PID=$2 # 设置性能测试工具路径 PERF_TOOLS_HOME=$(pwd) # 设置结果目录 GEN_RESULTS_DIR=$PERF_TOOLS_HOME/gen-flame-graphs-result # 设置 Java 运行参数 JAVA_HOME="/usr/java/home/bin/java.exe" # 生成 perf.data 数据 generate_perf_data() { echo "Perf record for all processors with sleep 30 seconds." cmd_perf="sudo perf record -F 99 -a -g -- sleep 30" eval $cmd_perf if [[ -e "$Perf_DATA" ]]; then echo "SUCCESS: perf.data was generated." else echo "ERROR: perf.data not generated; edit $0 and fix." fi } # 生成 Flame 图的脚本 generate_flame_graph() { # 创建堆栈脚本 cmd_stack="sudo perf script|$FLAME_GRAPH_PL_HOME/stackcollapse-perf.pl --pid|$FLAME_GRAPH_PL_HOME/flamegraph.pl --color=java --width=800 --minwidth=0.5 --title=\"$PID flame graph\" --hash > $FLAME_GRAPH_GENERAGED_FILE" eval $cmd_stack # 启动堆栈脚本 nohup $cmd_stack & # 获取 Flame 图文件路径 MAP_FILE="/home/q/flamegraph/perf-map-agent/out/$FLAME_GRAPH_GENERAGED_FILE" # 生成 Flame 图 echo "generate map file" chown root $MAP_FILE chmod 666 $MAP_FILE } # 检查环境变量是否正确设置 check_env() { check_envperf_recordgen_map_filegen_flame_graph_echo="SUCCESS: generate flame graph." } # 检查环境变量是否正确设置 check_envperf_recordgen_map_filegen_flame_graph() # 执行脚本 generate_perf_data generate_flame_graph ``` **使用方法:** 1. 将脚本中的 `sleep_seconds` 和 `pid` 设置为您要采样的秒数和进程 ID。 2. 将 `JAVA_HOME` 设置为您的 Java 运行器的路径。 3. 将 `GEN_RESULTS_DIR` 设置为您要存储结果的目录。 4. 运行脚本:`./gen-flame-graph.sh 30 8708` **注意:** * 该脚本需要在您系统上安装 `libperfmap.so` 文件。您可以通过使用 `find` 命令在您的系统中搜索 `libperfmap.so` 文件。 * 如果您无法找到 `libperfmap.so` 文件,请确保 Java 运行环境已安装了 `libperfmap.so`。 * 生成火焰图可能需要一些时间,具体取决于您的系统性能。

正文

https://www.dazhuanlan.com/smallnight/topics/1040103

 

在做性能调优的时候,我们通常会借助一些性能分析工具(比如 perf,DTrace)分析系统资源的使用情况,比如 CPU、内存等,但这些工具分析的结果通常是文本形式,不够直观,不便于快速定位系统瓶颈。Brendan Gregg开发了一种可视化的性能分析工具–火焰图,这种工具通过分析包含 stack traces 的 profile 数据,以可视化的形式展现出来,通过它可以快速准确地定位到热点代码。

本文内容涵盖了如何理解火焰图、如何生成火焰图、火焰图有哪些缺陷、如何解决这些缺陷、以及 Java 混合模式火焰图的具体生成步骤和具体实例。

火焰图 (Flame Graph)

针对不同的资源和事件类型,有不同类型的火焰图,主要包括:CPUMemoryOff-CPUHot/Cold以及Differential
我们先看一个 CPU 火焰图是什么样的,整个火焰图看起来是不是像一团火焰,这正是以火焰图命名的原因。本文中所描述的火焰图默认是指 CPU 火焰图。

 

 

 

理解火焰图

Brendan Gregg 在Blazing Performance with Flame Graphs一文中对如何解读火焰图有详细的介绍。

 

 

  • 小方块
    每个小方块代表一个函数,对应一个栈帧(stack frame),小方块的宽度表示该函数在采样期间出现的频率,宽度越宽表示出现的频率越高

栈帧:用于记录函数的活动记录,保存函数局部变量,函数参数等信息
因此要想分析出函数调用堆栈关系,就需要采样到栈帧信息。

  • Y 轴
    表示函数的调用栈,体现出了 stack 深度,每个垂直方向的顶端小方块表示正在使用 CPU(on-CPU)的函数
  • X 轴
    表示采样数据的总量,X 轴显示的数据是在对调用栈进行合并之后的结果,然后根据函数的字母顺序进行排列,X 轴并不代表使用 CPU 的时间长短,而只是说明该方法出现的次数,宽度越宽表示该方法出现的次数越多。国内不少文章将 X 轴直接看作为使用 CPU 的时间长短,这样理解并不准确。
  • 颜色
    小方块的颜色并没有特定的含义,是随机选取的暖色色调而已。

如何生成火焰图

生成火焰图只需要两步操作:(1)采集 stack traces 数据,(2)使用 FlameGraph 脚本生成火焰图。
perf是最常用的采集 stack traces 数据的工具。下图显示了 perf 的工作流程,其中 perf record 展示了生成火焰图的主要步骤。

 

图中的脚本 stackcollapse-perf.pl 和 flamegraph.pl 由火焰图工具FlameGraph提供

 

  • 采集 stack traces 数据

由于火焰图是根据任何包含 stack traces 的 profile 数据生成的,所以首先必须采集 stack traces 数据。以下列举的 profiling 工具都可以采集 profile 数据

Linux: perf_events(简称 perf) , eBPF, SystemTap, and ktap
Solaris, illumos, FreeBSD: DTrace
Mac OS X: DTrace and Instruments
Windows: Xperf.exe

perf是最常用的采集 stack 数据工具,通过 perf 采集数据时会在当前目录下生成 perf.data 文件。执行以下命令就可以完成数据采集。

1
sudo perf record -F 99 -a -g -- sleep 30

如果 Linux 系统未安装 perf,可参考以下命令安装 perf

1
sudo yum install perf

更多 perf 的使用示例可参考perf-examples

  • 生成火焰图
    stack traces 数据采集完之后,通过FlameGraph提供的 python 脚本就可以生成火焰图。
1
sudo perf script | ./stackcollapse-perf.pl | ./flamegraph.pl > out.svg

perf script 会默认在当前目录下查找通过 perf 生成的 perf.data 文件。FlameGraph提供了很多脚本,具体的使用方式可以参考官网示例。

perf script: 读取 perf.data 的文件内容,并以多行的形式生成 stacks
stackcollapse-perf.pl: 将多行形式的 stacks 折叠成一行记录
flamegraph.pl: 根据折叠之后的 stacks 信息生成 svg 格式的火焰图

该 svg 格式的火焰图内嵌了 JS 代码,通过浏览器打开,自带了交互功能:鼠标移动显示方法信息、可以点击放大或者缩小调用栈以及通过表达式查找对应的方法名。

火焰图的缺陷

通过 perf 等工具生成的火焰图只显示内核函数的调用栈,并不显示 Java 的调用栈(stack)和方法 (method),所以火焰图无法直接定位 Java 出是哪个方法比较耗 CPU,这正是火焰图的缺陷。
为了解决火焰图不显示 Java 的调用栈(stack)和方法 (method) 这个缺陷,Brendan Gregg 对火焰图工具进行了改进,创造出一种名为 Java 混合模式火焰图,这种火焰图即显示系统调用栈又显示 Java 调用栈和方法,将这两类信息都混合在一起,展现在一个图中,混合模式火焰图因此而命名。

Java 混合模式火焰图

Brendan Gregg 是如何解决这个问题的呢?如果你对这个部分的内容不感兴趣,可以直接跳过。
究竟是什么原因导致无法显示 method 以及完整的 stack 呢?

  • 为什么不显示 method
    原因在于 JIT 在编译 method 时,并没有暴露出一个 symbol table,导致 profiler 工具无法获取具体的 method。
  • 为什么 statck 不完整
    原因在于在 x86 (RBP on x86–64) 上,JVM 使用 frame 指针寄存器作为通用的寄存器,这种寄存器打破了传统的 stack 的运行方式,导致 stack 不完整。

如何解决显示 method 名称的问题

要想解决显示 method 名称这个问题,首先要能够收集到 symbols 信息,然后再从这些信息中识别出 method 名称

  • 如何收集 symbols 信息
    2014 年 Johannes Rudolph 写了一个名为perf-map-agent的开源 Java 代理,通过这个代理可以对 Java 应用生成/tmp/perf-PID.map 文件。这个文件里面记录了所有 symbol 的地址(十六进制)、大小和名称。所以通过 perf-map-agent 就可以解决收集 symbols 信息的问题。

perf-map-agent 是一个开源的 Java 代理,它包括一个用 C 写的 Java 代理以及一个可以将这个代理 attach 到 Java 进程的简易 Java 代码

  • 如何从 symbols 中识别 method
    2009 年,perf 已经支持了JIT symbol,通过这个特征 perf 会默认地查找/tmp/perf-$PID.map 文件,从该文件中解析出 function symbol 的信息,从而识别出 method 名称。

如果找不到 function symbol 信息,当前版本的 perf 脚本的处理方式是采用 library 的名字或者 perf-$PID.map 文件名作为 method 的名字

所以结合 perf 以及 perf-map-agent 就可以在火焰图上显示出 Java method。

  • 显示不显示 Java method 的效果对比

 

显示JAVA method
 

 

 

不显示JAVA method
 

 

如何解决 stack 不完整的问题

多年来编译器一直在不断地持续优化,gcc 编译器使用了 frame pointer,这种技术打断了 stack 的调用栈,使得 stack 不完整。然而在使用 gcc 时,如果使用了-fno-omit-frame-pointer 选项,就会显示完整的 stack。但是 JVM 并没有对应的选项对否显示完整的 stack 进行控制。

如果 JVM 能够实现一个选项,那么就可以解决 stack 不完整的问题。

这个特征能不能在 JDK 中实现呢?技术大咔 Brendan Gregg 出于好奇,他在 OpenJDK8 上开发了一个可以工作的原型,并期望能够在 Oracle JDK 中实现这个特征,于是他在 hotspot-compiler-dev 开发邮件组中发了一封邮件,低调地表达了自己不是资深的 hotspot 工程师,希望有人可以继续优化或者重写他写的这个原型。

hotspot-compiler-dev 社区将这个特性分别记录在 JDK9 的JDK-8068945和 JDK8 的JDK-8072465中。Oracle 的工程师 Zoltán Majó为了重写了这个 patch 做了大量的工作,四个月后终于完成,将这个特性集成在 JDK9 和 JDK8(JDK8 update 60 build 19)的发布版本里,使用选项 -XX:+PreserveFramePointer 控制是否显示完整的 stack。

因此通过打开 -XX:+PreserveFramePointer 就解决了 stack 不完整的问题,前提是 JDK 的版本必须大于或者等于Java 8 update 60 build 19

  • stack 是否完整的火焰图对比

 

 

 

 

如何生成 Java 混合模式火焰图

  • 安装 perf

安装 perf 之前,先 check OS(Linux 环境)是否已经安装过

1
perf --version

如果 perf 已经安装过,可以跳过安装这一步;如果未安装,执行以下命令完成安装

1
sudo yum install perf
  • 安装perf-map-agent

    • 安装 gcc 和 gcc-c++
    12
    sudo yum install gccsudo yum install gcc-c++

    如果系统中已安装 gcc 和 gcc-c++,这一步可以跳过。

    • 安装 cmake

    下载 cmake2.8.6,解压到/home/q/perf-tools/下

    1234
    sudo mkdir /home/q/perf-toolscd /home/q/perf-tools/cmake-2.8.6sudo  ./configure --prefix=/home/q/cmake-2.8.6sudo make && make install

    最好安装 cmake2.8.6,因为我曾尝试过安装最新版本的 cmake,但是在使用 cmake 编译 perf-map-agent 时失败,后来使用 cmake2.8.6 可以成功安装 perf-map-agent。

    • 安装 perf-map-agent
    123
    git clone https://github.com/jvm-profiling-tools/perf-map-agentcd /home/q/perf-tools/perf-map-agentsudo /home/q/cmake-2.8.6/bin/cmake . && sudo make

     

  • 配置 Java 选项
    JDK>=Java 8 update 60 build 19,选型 **-XX:+PreserveFramePointer** 才能生效

    • 检查 JDK 版本
    1
    java -version

    JDK 版本是否大于或者等于Java 8 update 60 build 19

    • 检查 JVM 参数
    1
    ps wwp `pgrep -n java`|grep PreserveFramePointer  --color

    检查 JVM 参数是否已经配置过选型 **-XX:+PreserveFramePointer**

    • 设置 **-XX:+PreserveFramePointer**
    1
    -Xms24g -Xmx24g -server -XX:+DisableExplicitGC -Dqunar.logs=$CATALINA_BASE/logs -Dqunar.cache=$CATALINA_BASE/cache -verbose:gc -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:+PrintGCApplicationStoppedTime -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGC -XX:+UseConcMarkSweepGC -XX:CMSFullGCsBeforeCompaction=1 -Xloggc:$CATALINA_BASE/logs/gc.log -XX:+PrintSafepointStatistics -XX:ReservedCodeCacheSize=512m -XX:CMSInitiatingOccupancyFraction=50 -XX:+UseCMSInitiatingOccupancyOnly -XX:MaxTenuringThreshold=14 -XX:+PreserveFramePointer

     

  • 安装FlameGraph

     

1
git clone https://github.com/brendangregg/FlameGraph.git
  • 生成脚本
    下面是一个包含数据采样和生成火焰图的脚本,因此通过一个脚本就能生成 Java 混合模式火焰图。使用方法:
1
sudo ./gen-flame-graph.sh $SLEEP_SECONDS $PID

具体的脚本内容:

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
#!/bin/bashSLEEP_SECONDS=$1PID=$2PERF_TOOLS_HOME=$(pwd)GEN_RESULTS_DIR=$PERF_TOOLS_HOME/gen-flame-graphs-resultAGENT_HOME=$PERF_TOOLS_HOME/perf-map-agentAGENT_JAR=$AGENT_HOME/attach-main.jarAGENT_OUT=$AGENT_HOME/outFLAME_GRAPH_PL_HOME=$PERF_TOOLS_HOME/FlameGraphFLAME_GRAPH_GENERAGED_FILE=$PERF_TOOLS_HOME/flamegraph-mixed-model-`date +%Y%m%d-%H%M%S`.svgMAP_FILE=/tmp/perf-$PID.mapfunction check_env(){  if [[ ! -x $JAVA_HOME ]]; then      echo "ERROR: JAVA_HOME not set correctly; edit $0 and fix"      exit  fi  if [[ ! -x $AGENT_HOME ]]; then      echo $AGENT_HOME      echo "ERROR: AGENT_HOME not set correctly; edit $0 and fix."      exit  fi  if [[ ! -x $GEN_RESULTS_DIR ]]; then      echo "ERROR: '$GEN_RESULTS_DIR' not found;Please mkdir a file :'$GEN_RESULTS_DIR'"      exit  fi}#generate perf.data with command: perf recordfunction perf_record(){  echo "Perf record for all processors with sleep 30 seconds."  cmd_perf="sudo perf record -F 99 -a -g -- sleep 30"  eval $cmd_perf  if [[ -e "./perf.data" ]]; then     echo "SUCCESS: perf.data was generated."  else     echo "ERROR: perf.data not generated;edit $0 and fix."     exit  fi}#agent mapping pidfunction gen_map_file(){  user=$(ps ho user -p $PID)  echo "Agent mapping PID $PID with user $user"  cmd_agent="cd $AGENT_HOME;java -cp attach-main.jar:$JAVA_HOME/lib/tools.jar net.virtualvoid.perf.AttachOnce $PID"  cmd_agent="sudo -u $user sh -c '$cmd_agent'"  eval $cmd_agent  if [[ -e "$MAP_FILE" ]]; then     echo "generate map file"     chown root $MAP_FILE     chmod 666 $MAP_FILE  else     echo "ERROR: $MAP_FILE not created."     exit  fi}#generate flame graphfunction gen_flame_graph(){  cmd_stack="sudo perf script|$FLAME_GRAPH_PL_HOME/stackcollapse-perf.pl  --pid|$FLAME_GRAPH_PL_HOME/flamegraph.pl --color=java --width=800 --minwidth=0.5 --title="$PID flame graph"  --hash > $FLAME_GRAPH_GENERAGED_FILE"  eval $cmd_stack}check_envperf_recordgen_map_filegen_flame_graphecho "SUCCESS: generate flame graph."

Java 混合模式火焰图实例

在根据上面的步骤安装完对应的工具之后,我们可以通过上面提供的脚本生成火焰图。下面这个实例是对 Java 进程 8708 采样 30 秒,然后生成名为 flamegraph-mixed-model-date +%Y%m%d-%H%M%S.svg 的 Java 混合模式火焰图。

1
sudo ./gen-flame-graph.sh 30 8708

执行脚本过程中,如果遇到以下错误

1
Expected libperfmap.so at '/home/q/flamegraph/perf-map-agent/libperfmap.so' but it didn't exist.

就需要 copy 文件 libperfmap.so,然后再次执行生成火焰图的脚本

1
cp /home/q/flamegraph/perf-map-agent/out/libperfmap.so  /home/q/flamegraph/perf-map-agent

生成的 Java 混合模式火焰图如下:

 

 

 

火焰图对系统性能的损耗

-XX:+PreserveFramePointer 对性能的影响
Orcale 的性能测试团队测试的结果是性能下降 2%-5%(SPECjvm2008-Derby* -2% to -5%),出于对性能的考虑,他们建议默认配置不启用 PreserveFramePointer
Netflex 的性能测试结果是性能下降 0-3%

火焰图的作者是何许人也?

下图是我们常见的 Linux 性能优化图,大家肯定见过多次。没错,这个图出自于Brendan Gregg,他正是火焰图的作者。

 

 

他现在是 Netflix 的高级性能架构师,主要工作是做大规模计算的性能设计、分析以及调优。之前在 Sun Microsystems 做一名 kernel engineer
也是《Systems Performance》(中文版本《性能之巅:洞悉系统、企业与云计算》) 一书的作者,该书荣获 2013 年的 USENIX LISA 大奖
也开发了很多性能分析工具,比如 DTrace
如果你对性能调优感兴趣,可以关注他的blog个人网站

参考资料
1.https://medium.com/netflix-techblog/java-in-flames-e763b3d32166
2.https://www.slideshare.net/brendangregg/javaone-2015-java-mixedmode-flame-graphs?qid=3245fe6e-33e7-41c8-b9d8-8bbefab56671&v=&b=&from_search=1

与[转帖]人工智能 Java混合模式火焰图相似的内容:

[转帖]人工智能 Java混合模式火焰图

https://www.dazhuanlan.com/smallnight/topics/1040103 在做性能调优的时候,我们通常会借助一些性能分析工具(比如 perf,DTrace)分析系统资源的使用情况,比如 CPU、内存等,但这些工具分析的结果通常是文本形式,不够直观,不便于快速定位系统瓶

[转帖]人工智能 Java混合模式火焰图

https://www.dazhuanlan.com/smallnight/topics/1040103 在做性能调优的时候,我们通常会借助一些性能分析工具(比如 perf,DTrace)分析系统资源的使用情况,比如 CPU、内存等,但这些工具分析的结果通常是文本形式,不够直观,不便于快速定位系统瓶

[转帖]存算一体芯片技术及其最新发展趋势

https://zhuanlan.zhihu.com/p/450985519 ■作者:陈巍 博士 资深芯片专家,人工智能算法-芯片协同设计专家,擅长芯片架构与存算一体。国内首个可重构存算处理器架构(已在互联网大厂完成原型内测),首个医疗领域专用AI处理器(已落地应用),首个RISC-V/x86/AR

[转帖]关基、等保、密评之间的关系

没有网络安全就没有国家安全,没有信息化就没有现代化,网络安全和信息化是一体之两翼、驱动之双轮”。随着5G、大数据、云计算、人工智能、工业互联网、物联网等新一代信息技术的发展,网络空间与物理空间被彻底打通,网络空间成为继“陆海空天”之后的第五大战略空间,愈演愈烈的网络攻击已经成为国家安全的新挑战。为保

[转帖]一月一盘点:12月,那些您错过的服务器领域新鲜事儿

http://blog.itpub.net/28285180/viewspace-2930414/ 数字化转型趋势下,各行业领域的信息数据呈爆发式增长。随着人工智能、云计算、物联网、大数据等前端科技的不断发展和延伸,各科技产业呈现良好发展态势。无论是企业还是个人,在新时代的环境下,都应紧跟数字化转型

[转帖]openGauss安全

https://cdn.modb.pro/db/585069 随着数字化技术的飞速发展,数字、连接、信号、人工智能充斥着人们工作、生活的各个领域。这些数字化信息被快速转换成数据并存放在各式各样的数据库系统中,而且通过进一步的数据管理与分析产生商业价值。这些有价值的数据或被存放在企业相对封闭的私有网络

【转帖】Meta 推出大型语言模型 LLaMA,比 GPT3.5 性能更高

https://finance.sina.com.cn/wm/2023-02-28/doc-imyihfvp8075151.shtml ChatGPT 的爆火使得大家对 AI 进行了深度的讨论,大厂们也都在向公众展示他们所谓的 "生成性人工智能"已经准备好进入黄金时代。 近日,Meta 宣布推出大型

[转帖]英伟达H100市面价格飙升!Elon Musk:每个人都在买GPU

https://cj.sina.com.cn/articles/view/5115326071/130e5ae7702001w8oz?sudaref=www.baidu.com&display=0&retcode=0 据外媒CNBC报道,随着对训练和部署人工智能软件所需芯片需求的飙升,英伟达的最先进

[转帖]存算一体技术是什么?发展史、优势、应用方向、主要介质(收录于存算一体芯片赛道投资融资分析/20220517更新)

https://zhuanlan.zhihu.com/p/480612865 本文深入浅出的介绍存算一体技术的概念、发展历史、技术优势、应用方向、主要介质、技术比对等。 作者 ■ 陈巍 博士 资深芯片专家,人工智能算法-芯片协同设计专家,擅长芯片架构与存算一体。国内首个可重构存算处理器架构(已在互联

[转帖]全球CPU市场格局(2022)

https://www.eet-china.com/mp/a222817.html 本文选自“2022年国产服务器CPU研究框架”,重点分析2022年CPU产业链、CPU市场规模、CPU全球市场格局和CPU全球主要厂商。 下载链接:2022年国产服务器CPU研究框架2021-2022年中国人工智能产