写点什么

Java 火焰图在 Netflix 的实践

  • 2015-08-04
  • 本文字数:1672 字

    阅读完需:约 5 分钟

为了分析不同软件或软件的不同版本使用 CPU 的情况,相关设计人员通常需要进行函数的堆栈性能分析。相比于定期采样获得数据的方式,利用定时中断来收集程序运行时的 PC 寄存器值、函数地址以及整个堆栈轨迹更加高效。目前, OProfile gprof SystemTap 等工具都是采用该方法,给出详细的 CPU 使用情况报告。然而,这些工具在处理复杂的统计数据时,给出的报告往往过于繁杂、不够直观、不能直接反应分析员所需要的数据。为此,Brendan Gregg 开发了专门把采样到的堆栈轨迹(Stack Trace)转化为直观图片显示的工具—— Flame Graph(火焰图)。但是,由于分析器与 JDK 环境等原因,Java 程序的混合模式火焰图之前无法生成。近期,Brendan Gregg 和 Martin Spier 发现了一种解决该问题的方法,在 Netflix 内部进行了实践,并贡献了一篇非常详尽的实践性文章。为Java 程序的性能分析提供了极大便利。接下来,本文就从该问题出现的原因开始,简要介绍其解决该问题的思路和方法。

首先,本文对火焰图的概念进行简要介绍。火焰图既是一个开源工具,也是一种类型的图片。作为一个二维图片,火焰图的X 轴代表采样总量,而Y 轴代表栈深度。每个框就代表了一个栈里的函数,其宽度代表了所占用的CPU 总时间。因此,比较宽的框就表示该函数运行时间较慢或被调用次数较多,从而占用的CPU 时间多。通过火焰图,相关设计或分析人员就可以轻松观察到各个应用占用CPU 的情况。

但是,火焰图本身并不具备性能检测的能力。它需要其他性能分析工具的协助。在Java 环境中,一共有两种类型的堆栈轨迹采样分析器——系统分析器(System Profiler)和JVM 分析器(JVM Profiler)。前者(如Linux 的 Perf Events )可以分析系统代码路径,包括 libjvm internal、GC 和内核,但并不能分析 Java 方法;后者(如 HPROF 、轻量级 Java 分析器和其他商业分析器)可以显示 Java 方法,但不能显示系统代码路径。由此可见,这两种方法都不能同时支持系统代码路径和 Java 方法的堆栈轨迹。而分别描述二者的火焰图又不能很好的满足需求。因此,Brendan 等人一直关注如何解决该问题。

在之前的一次讨论中,Brendan 曾经对系统分析器不能显示Java 方法的原因进行分析。这包括两个方面——JVM 编译方法时比较快,没有为系统分析器暴露一个符号表;JVM 采用x86 上的frame pointer 作为一个通用寄存器,破坏了传统的stack walking。那么,解决之前的问题,就需要分别从这两个方面入手。对于第一个方面,Java 和Linux 系统的分析器进行了双方面的努力。首先,Java 开始支持利用开源的JVMTI 代理 perf-map-agent 来创建 perf-PID.map 文本文件。该文件列举了 16 进制的符号地址、大小以及符号名称。然后,从 2009 年以后,Linux 中的 Perf_events 工具添加了对 JIT 符号的支持。该工具会检查 /tmp/perf-PID.map 文件,从而完成对来自语言虚拟机的符号进行检查。对于第二个方面,JVM 添加了一个新的选项 -XX:+PreserveFramePointer。经过 Zoltán、Oracle 和其他工程师的努力,最新的 JDK9 JDK8 已经增加了该选项,从而保存了 stack walking。

在两方面的问题都解决之后,用户只要经过安装 Perf Events、新版 JDK、perf-map-agent 以及 FlameGraph 等软件和配置 Java(尤其是打开 -XX:+PreserveFramePointer 选项)的步骤后,就可以产生系统级的火焰图了。为了让产生火焰图的流程自动化,Brendan 等人已经开始基于开源的实例化分析工具 Vector 进行流程的建模。

未来,Breden 等人还计划进行很多工作。其一是通过自动化收集不同日期的差分火焰图进行规则分析。这有助于迅速理解软件变化所导致的 CPU 使用率变化。此外,他们还试图利用 Perf Events 进行磁盘 IO、网络、调度以及内存分配等用户和内核级的事件记录和分析。最后,对火焰图和 Vector 进行实时更新等改进也是未来考虑增加的功能。


感谢徐川对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ @丁晓昀),微信(微信号: InfoQChina )关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入 InfoQ 读者交流群)。

2015-08-04 06:518869
用户头像

发布了 268 篇内容, 共 131.3 次阅读, 收获喜欢 24 次。

关注

评论

发布
暂无评论
发现更多内容

「文本检测与识别白皮书-3.2」第三节:常用的文本识别模型

合合技术团队

人工智能 机器学习 深度学习 模型 文字识别

字节跳动开源数据集成引擎BitSail的演进历程与能力解析

字节跳动数据平台

数据库 开源 数据开发 数据集成 企业号十月 PK 榜

网络爬虫技术及应用

郑州埃文科技

网络安全 IP地址资源 爬虫技术

WEB项目如何通知用户在线更新?

GFE

前端 版本管理

前端 30 问:愿你能三十而立

GFE

面试 前端

拥抱“大信创”浪潮,优博讯开启成长新曲线

极客天地

分布式锁实战:基于Zookeeper的实现

小小怪下士

Java zookeeper 分布式

平均110万个漏洞被积压,企业漏洞管理状况堪忧

SEAL安全

DevSecOps 漏洞修复 软件供应链安全 漏洞管理 漏洞优先级匹配

云转售是什么意思?哪家好?理由是什么?

行云管家

云计算 企业上云 云资源 云转售

堡垒机按什么收费?大概多少钱?有一个标准吗?

行云管家

网络安全 堡垒机 IT安全

【重磅】Serverless Devs 进入 CNCF 沙箱,成首个入选的 Serverless 工具项目!

阿里巴巴云原生

阿里云 Serverless 云原生

软件测试面试真题 | 说一下常用的控件定位方法

测试人

软件测试 面试题 web测试 元素定位

量化合约对冲挖矿app软件开发案例(支持测试)

开发微hkkf5566

扒官方文档学Ts类型编程(二)

GFE

typescript 前端

详解AQS中的condition源码原理

华为云开发者联盟

开发 华为云 企业号十月 PK 榜

三位技术大咖的「研发效能」实践干货

万事ONES

研发效能 课程笔记

Spring Boot「22」使用 Hibernate & JPA 持久化 Java 对象

Samson

Java hibernate Spring Boot 学习笔记 11月月更

python小知识-classmethod类方法

AIWeker

Python 人工智能 python小知识 11月月更

7k字,12张图,从零到一带你详解Redis

Java永远的神

数据库 nosql redis 程序员 面试

【愚公系列】2022年11月 Go教学课程 040-字符串处理

愚公搬代码

11月月更

IM消息ID技术专题(七):网易严选分布式ID的技术选型、优化、落地实践

JackJiang

网络编程 即时通讯 IM 开源im

NGINX Sprint 年度线上会议:报名通道已开启,立即预定您的 NGINX 深潜之旅

NGINX开源社区

nginx

图解vue3.0编译器核心原理

GFE

前端 Vue3

详解linux多线程——互斥锁、条件变量、读写锁、自旋锁、信号量

C++后台开发

多线程 后端开发 linux开发 C++开发

详解 Serverless 架构的 6 大应用场景

阿里巴巴云原生

阿里云 Serverless 云原生

扒官方文档学Ts类型编程

GFE

typescript 前端

Discount-industrial mini pcie card/Dual Band 2.4GHz 5GHz 2x2 MIMO 802.11ac Mini PCIE WiFi Module//QCA9880 3x3 FCC/CE/IC

Cindy-wallys

QCA9880 802.11ac 3*3 2*2 2.4G&5G

Go语言入门12—异常

良猿

Go golang 后端 11月月更

NFTScan 与 Bitizen 钱包达成战略合作,双方将在 NFT 数据层面进行深度合作

NFT Research

NFT 数据基础设施

图数据 3D 可视化在 Explorer 中的应用

NebulaGraph

可视化 图数据库 3D

Go语言躲坑经验总结

百度Geek说

Go 企业号十月 PK 榜

Java火焰图在Netflix的实践_Java_张天雷_InfoQ精选文章