上周一个偶然的机会听同事提到了Java FlameGraph,刚实验了一下,效果非常好。

一、什么是FlameGraph

直接看图说话。FlameGraph 是 SVG格式,矢量图,可以随意扩大缩小,看不清的信息可以放大看。图中,各种红橙黄色没有什么意义,仅仅做区分用;x轴横条宽度来度量时间指标,表明每个接口实际占用的CPU时间;y轴代表线程栈的层次,从最底下往上表示堆栈的层层调用。通过看图,可以发现哪个接口占用的CPU时间较多,从而优化;同时,可以发现调用关系。

Java火焰图的作者是Brendan Gregg,他的博客非常有意思,很多关于性能的分析。以下链接是对每个类别的火焰图的详细说明。

什么是Java Flame Graphs:Java Flame Graphs

On-CPU:CPU Flame Graphs

Off-CPU:Off-CPU Flame Graphs

Memory:Memory Leak (and Growth) Flame Graphs

Hot/Cold:Hot/Cold Flame Graphs

Differential:Differential Flame Graphs

关于火焰图的PPT(讲解得非常详细):Blazing Performance with Flame Graphs

二、如何生成

两个步骤:1. 需要java profiler生成trace文件  2. 将trace文件转换为svg格式的火焰图文件。

1. 需要java profiler生成trace文件

在使用Profiler对CPU进行采样时,根据CPU当前执行所处栈位置以及各个函数栈在总的采样次数所占比例就可以得出各个函数执行时的CPU占用比例。常用的是lightweight-java-profiler。还有其他的选择,比如honest-profiler,lightweight-java-profiler会从java虚拟机启动开始采样,而有时候我们需要在CPU飙高的时候开始,这时候honest-profiler提供的动态启停功能就有用武之地了。也有使用perf生成火焰图。(*perf 要研究一下)

下面以lightweight-java-profiler 举例

(1) 从github下载软件

(2) 编译 make all

(3) 生成的程序存放在build-64文件夹下面

(4)(可选)可以更改一些lightweight-java-profiler的一些选项,打开src/globals.h文件。在长时间采样时,可以适当地减少每秒采样次数,不然最终生成的文件会很大,分析起来比较麻烦。

// 每秒采样频率
static const int kNumInterrupts = 100;
// Maximum number of stack traces线程栈个数
static const int kMaxStackTraces = 3000;
// 采样栈深度
static const int kMaxFramesToCapture = 128;  

  kNumInterrupts: 每秒钟抽取样本的次数;

  kMaxStackTraces: 线程栈的最大数量   

  kMaxFramesToCapture: 线程栈的深度

(5)运行Java程序

  java -agentpath:path/to/liblagent.so ......

(6)java程序启动后会在当前目录生成一个traces.txt文件,但文件中只有一些说明信息。程序正常结束(不杀掉进程)后,才会写入具体采样信息。

2.将trace文件转换为svg格式的火焰图文件。

(1)从github下载FlameGraph

(2)转换

./stackcollapse-ljp.awk < traces.txt | ./flamegraph.pl > traces.svg
(3)浏览器中打开traces.svg文件
三、简单讨论一下Java profiler
关于采样工具的选取,可以看看文章 Evaluating the Accuracy of Java Profilers ,这里面列举了xprof,hprof,jprofile和yourkit四种采样器,并通过几个压测场景证明了这几种采样器的结果是相互矛盾的。总结的原因有两点:
1. 采样器采样点不够随机,这几种采样器都只有在safe point采样;
2. 不同的采样器会注入不同的代码,从而影响程序优化过程,同时也影响了safe point的分布,进一步造成采样差异;
honest-profiler号称是避开了通过SUN/Oracle management agent去采样堆栈,而是使用自己实现的使用UNIX 操作系统信号和为Oracle Performance Studio 设计的内部API的sampling agent,从而提升了采样准确率。
还有一篇文章和 Why many profilers have serous problems。
Java profiler 的两个常见方式:
1.修改代码,从而实现采样。问题是:1. 增加开销;2. 修改了你的代码,导致java编译器的优化行为不确定;3. 影响了代码的层次,层次越深自然也影响 执行效率。
2.通过获取on-cpu线程的线程栈方式。问题是:获取系统范围的线程栈,jvm必须处于safepoint状态(看文章What is Java safepoint)。只有当线程处于safepoint状态的时候,别的线程才能去获取它的线程栈,而这个safepoint是由jvm 控制的,这对于profiler非常不利,有可能一个很热的代码块,jvm不会在该代码块中间放置safepoint,导致profiler无法获得该线程栈,导致错误的profiler结果。

几个商用的profiler工具都存在上述问题。但是,Oracle Solaris studio利用的是jvmti的一个非标准接口AsyncGetCallTrace来实现,不存在上面问题,Jeremy Manson也利用该接口 实现了一个简单的profiler工具:lightweight-java-profiler。

相关知识:
部分内容摘自 http://blog.csdn.net/c395318621/article/details/55224665
部分内容摘自 http://tacy.github.io/blog/2014/07/16/FlameGraph/
部分内容摘自 http://www.javashuo.com/content/p-6579579.html
部分内容摘自 http://colobu.com/2016/08/10/Java-Flame-Graphs/
文章: Evaluating the Accuracy of Java Profilers  
文章: Why many profilers have serous problems。
文章: What is Java safepoint

转载于:https://www.cnblogs.com/xingzifei/p/7446264.html

Java FlameGraph 火焰图相关推荐

  1. java火焰_使用linux perf工具生成java程序火焰图

    Java FlameGraph(火焰图)能够非常直观的展示java程序的性能分析结果,方便发现程序热点和进一步调优.本文将展示如何使用linux perf工具生成java程序的火焰图.火焰图大致长这个 ...

  2. linux实现字符火焰动画,linux flamegraph火焰图使用

    perf可以忽略语言或者一些开发框架,从os的角度看到进程的cpu时间都耗费在哪些调用栈上. perf与火焰图搭配使用,提供一个比较友好的交互方式,来观察调用栈的耗时 验证环境是ubuntu环境 安装 ...

  3. java 性能调优,使用 async-profiler + FlameGraph火焰图 分析cup消耗热点代码

    参考文章 https://www.jianshu.com/p/9364028cca4e 目的:通过分析工具找到项目中占用cpu时间最长的代码片段,优化热点代码,达到优化内存的效果. 1.准备工具,从g ...

  4. 火焰图 性能分析 java,使用火焰图进行Java应用性能分析

    作者: 一字马胡 转载标志 [2017-11-19] 更新日志 日期 更新内容 备注 2017-11-19 新建文章 初版 导入 本文主要想要记录进行java应用性能分析的一种方式,也就是使用火焰图来 ...

  5. 【初探】java性能火焰图的生成

    前言 开始之前,你需要准备的环境: Linux系统机器或者虚拟机一台,里面需要安装的软件:git.jdk.perl. 简单介绍: java性能分析火焰图的所做的事情就是能够分析出java程序运行期间存 ...

  6. java 性能 火焰图_性能调优工具-火焰图

    性能调优工具-火焰图 发布时间:2019-07-17 19:29, 浏览次数:402 前言 工具的进化一直是人类生产力进步的标志,合理使用工具能大大提高我们的工作效率,遇到问题时,合理使用工具更能加快 ...

  7. java 性能 火焰图_flamegraph(火焰图)性能分析

    使用perf工具以及flamegraph可以将调试的程序运行栈以及在每个函数中停留的时间以火焰图的形式展现出来. perf工具可以在内核源码tools/perf中编译安装. make &&am ...

  8. java实例_图例 | Java混合模式分析之火焰图实例

    这是小小的第五篇 前言 在进行性能调优的时候,通常会借助性能分析工具,常用的性能分析工具有perf,DTrace,分析系统资源的使用情况,这些情况根据CPU,内存,生成相关的文本数据,这些文本数据不容 ...

  9. 图例 | Java混合模式分析之火焰图实例

    这是小小的第五篇 前言 在进行性能调优的时候,通常会借助性能分析工具,常用的性能分析工具有perf,DTrace,分析系统资源的使用情况,这些情况根据CPU,内存,生成相关的文本数据,这些文本数据不容 ...

最新文章

  1. 深度学习中用于张量重塑的 MLP 和 Transformer 之间的差异图解
  2. element not visible的解决方法
  3. 修改maven本地仓库位置
  4. 编写多线程Java应用程序常见问题
  5. Linux实战案例(4)CentOS清除用户登录记录和命令历史方法
  6. 史诗级pg脚本,亲测好使
  7. 绝对布局优势_街电福建全场景布局持续深化,构建全时续电服务强化行业领先优势...
  8. MySQL 开源工具集合
  9. Kali学习笔记15:防火墙识别、负载均衡识别、WAF识别
  10. Python是否支持短路?
  11. CodeBlock代码替换
  12. Excel中排序和筛选
  13. 高等数学:第六章 定积分的应用(4)平面曲线的弧长
  14. 深度学习之鸡兔同笼问题
  15. 408 知识点笔记——操作系统(绪论、进程管理)
  16. 中国非处方彩色美瞳隐形眼镜行业销售动态与营销前景预测报告2022-2027
  17. 卷积神经网络 图像处理,卷积神经网络图像识别
  18. Go-加密学(六) - BEGIN CERTIFICATE、BEGIN RSA PRIVATE KEY和BEGIN PRIVATE KEY的区别
  19. ps技术的革命创新-photoshop beta版
  20. LTE上行链路反馈MCS(计算MCS、调制阶数、编码速率、频谱效率关系表格)

热门文章

  1. 关联关系、依赖关系总结
  2. How to make a difference
  3. ADO.Net 事务操作
  4. 消息队列mysql redis那个好_Redis与RabbitMQ作为消息队列的比较
  5. 5. 多线程程序如何让 IO 和“计算”相互重叠,降低 latency?
  6. linux上很方便的上传下载文件工具rz和sz
  7. Matlab去掉矩阵中的全0行或列
  8. webservice生成客户端的方法
  9. matlab短均线滞后项,均线理论的滞后性问题
  10. uni-app动态绑定class和style