又一款性能调优神器,真香!(代码片段)

Java技术栈 Java技术栈     2023-01-23     462

关键词:

点击关注公众号,Java干货及时送达

来源:https://zhenbianshu.github.io

前言

工具的进化一直是人类生产力进步的标志,合理使用工具能大大提高我们的工作效率,遇到问题时,合理使用工具更能加快问题排查的进度。这也是我为什么非常喜欢 shell 的原因,它丰富的命令行工具集加管道特性处理起文本数据集来真的精准而优雅,让人迷醉。

但很多时候文本的表现力非常有限,可以说匮乏,表达绝对值时,自然是无往不利,但在展示相对值时,就有些捉襟见肘了,就更不用说多维数据了。

我们用 shell 可以非常快速地查询出文本内的累加值、最大值等,但一遇到两组值的相关性分析时,就束手无策了。这个时候,就需要使用另一种分析工具 – 了,如散点图就能很清晰地展示相关性。

今天就准备介绍一种图,火焰图,之前组内大神分享过它的使用办法,但我之后很久都没有用过,以至于对它没有什么深刻印象,最近排查我们 Java 应用负载问题时试用了一下,这才对它的用途有了点心得。

介绍

引子

在排查性能问题时,我们通常会把线程栈 dump 出来,然后使用 grep --no-group-separator -A 1 java.lang.Thread.State jstack.log | awk 'NR%2==0' | sort | uniq -c | sort -nr 类似的 shell 语句,查看大多数线程栈都在干什么。而由线程栈的出现频率,来推断 JVM 内耗时最多的调用。46 张 PPT 弄懂 JVM 性能调优

至于其原理,设想广场上有一个大屏幕在不停地播放各种广告。如果我们随机对大屏幕拍照,次数多了,统计照片中各个广告出现的频率,基本可以得出每个广告的播放时长占比了。

而我们应用的资源就像大屏幕,每次调用就像是播放一次广告,统计 dump 出的线程栈出现比例,也就基本能看出线程栈的耗时占比,虽然有误差,但是多次统计下应该差不了多少。这也就是为什么有些家长每次进孩子房间都发现孩子在看系统桌面后以为孩子平时喜欢对着桌面发呆的原因。:)

2444  at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1200)
1587  at sun.misc.Unsafe.park(Native Method)
795  at java.security.Provider.getService(Provider.java:1035)
293  at java.lang.Object.wait(Native Method)
292  at java.lang.Thread.sleep(Native Method)
 73  at org.apache.logging.log4j.core.layout.TextEncoderHelper.copyDataToDestination(TextEncoderHelper.java:61)
 71  at sun.nio.ch.EPollArrayWrapper.epollWait(Native Method)
 70  at java.lang.Class.forName0(Native Method)
 54  at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.checkRollover(RollingFileManager.java:217)

但是这样有些问题,首先写 shell 挺费事的,另外如果我想查看自栈顶第二个栈的最多调用,即使修改了 shell 命令,结果也不直观。

产生这个问题的主要原因是,我们的线程栈是有调用关系的,即我们需要考虑线程栈的 调用链出现频率 两个维度,而单一的文本表现这两种维度比较困难,所以,著名性能分析大师 brendan gregg 就提出了火焰图。

点击关注公众号,Java干货及时送达

介绍

火焰图,因其形似火焰而得名,其开源代码地址:

https://github.com/brendangregg/FlameGraph

它是一种 svg 可交互式图形,我们通过点击和鼠标指向可以展示出更多的信息。下图就是一个典型的火焰图,从结构上,它是由多个大小和颜色各异的方块构成,每个方块上都有字符,它们底部连接在一块,组成火焰的基底,顶部分出许多”小火苗”。

当我们点击方块时,图片会从我们点击的方块为基底向上展开,而我们鼠标指向方块时,会展示出方块的详细说明。

最新面试题整理好了,点击Java面试库小程序在线刷题。

特性

介绍火焰图的分析前,我们要首先说明它的特性:

分析

那么,给我们一张火焰图,我们怎么能看出系统哪里有问题呢?

由上文中的火焰图特性特性,查看火焰图时,我们最主要的关注点要放在方块的宽度上,因为宽度代表了调用栈在全局出现的次数,次数代表着出现频率,而频率也就可以说明耗时。

但是观察火焰图底部或中部方块的宽度占比意义不大,如上面的火焰图,中部的 do_redirections 函数宽度是 24.87%,也就是说它耗用了整个应用近四分之一的时间,但是真正消耗时间的并不是 do_redirections 函数,而是 do_redirections 内部又调用的其他函数,而它的子调用分为了很多个,每个调用的耗时并没有异常。

我们更应该关注的是火焰图顶部的一些 “平顶山”,顶部说明它没有子调用,方块宽说明它耗时长,长时间 hang 住,或者被非常频率地调用,这种方块指向的调用才是性能问题的罪魁祸首。

找到了异常调用,直接优化它,或者再根据火焰图的调用链层层向下,找到我们的业务代码进行优化,也就大功告成。

推荐一个 Spring Boot 基础教程及实战示例:https://github.com/javastacks/javastack

应用场景

每种工具都有其适合的应用场景,火焰图则适合用在:

实现

既然火焰图这么强大,那么我们该怎么实现呢?

生成工具

brendan gregg 大神已经把生成火焰图的方法用 perl 实现了,开源代码就在上文的 Github 仓库中,根目录下的 flamegraph.pl 文件就是可执行的 perl 文件了。

这个命令还可以传入各种参数,支持我们修改火焰图的颜色、大小等 。另外,JVM 系列面试题和答案全部整理好了,微信搜索Java技术栈,在后台发送:面试,可以在线阅读。

但 flamegraph.pl 只能处理特定格式的文件,像:

a;b;c 12
a;d 3
b;c 3
z;d 5
a;c;e 3

前面是调用链,每个调用之间用 ; 隔开,每行后面的数字是调用栈出现的次数。

如上面的数据,用 flamegraph.pl 生成的火焰图如下图:

数据准备

至于我们的 jstack 信息如何被处理成上面的格式,大神则为常见的 dump 格式都提供了工具,像 stackcollapse-perf.pl可以处理 perf 命令的输出,stackcollapse-jstack.pl 处理 jstack 输出,stackcollapse-gdb.pl 处理 gdb 输出的栈等。

也可以用 shell 简单地实现一下 jstack 的处理方式:

grep -v -P '.+prio=d+ os_prio=d+' | grep -v -E 'locked <' | awk 'if ($0=="")print $0elseprintf"%s;",$0' | sort | uniq -c | awk 'a=$1;$1="";print $0,a'

小结

火焰图总结完了,以后再遇到性能问题又多了一种应对方式。

做开发越久,越能感受得到工具的重要性,所以我准备加一个专题来专门介绍我使用的各种工具。当然,这也就更需要我更多地了解、使用和总结新的工具了。



关注Java技术栈看更多干货

获取 Spring Boot 实战笔记!

又一款接​私活神器!springboot+vue通用后台管理系统,真香!!

...势,什么值得学!参考:https://el-admin.vip/guide/又一款接私活神器,统一后台系统,前后端分离,别再乱找了!这是一款基于SpringBoot2.1.0、Jpa、SpringSecurity、redis、Vue的前后端分离的 查看详情

又一款nginx管理可视化神器!通过界面完成配置监控,一条龙!(代码片段)

来自:Nginx-GUI入门链接:https://leanote.zzzmh.cn/blog/post/5cc7f63616199b068300001c需求nginx可视化管理,例如配置管理性能监控日志监控其他配置方案目前已实现前两条:配置管理,和性能监控日志分析监控这块还需要另找方... 查看详情

推荐一款开源的shell装逼神器,真香!(代码片段)

👇👇关注后回复 “进群” ,拉你进程序员交流群👇👇来源公众号丨Java面试那些事儿来源:https://github.com/nushell/nushell今天,我要给大家介绍一个生产力工具(装逼神器)Shell,它叫Nushell,它是用Rust... 查看详情

c#组件系列——又一款excel处理神器spire.xls(代码片段)

...索结果高亮九、总结正文前言:上篇 C#组件系列——又一款Excel处理神器Spire.XLS,你值得拥有(一 查看详情

c#组件系列——又一款excel处理神器spire.xls(代码片段)

阅读目录一、组件介绍二、组件安装使用1、官方下载安装2、Nuget安装三、组件功能介绍1、Excel转PDF2、Excel生成图表3、其他功能介绍四、总结正文前言:最近项目里面有一些对Excel操作的需求,博主想都没想,NPOI呗... 查看详情

c#组件系列——又一款excel处理神器spire.xls(代码片段)

...索结果高亮九、总结正文前言:上篇 C#组件系列——又一款Excel处理神器Spire.XLS,你值得拥有(一) 介绍了下组件的两个功能,说不上特色,但确实能解决我们项目中的一些实际问题,这两天继续研... 查看详情

推荐一款开源的shell装逼神器,真香!

今天,我要给大家介绍一个生产力工具(装逼神器)Shell,它叫Nushell,它是用Rust写的,安全性提高的同时,Bug率也降低了,NuShell专注于实现以下目标:1、创建具有现代感的灵活的跨平台Shell2、允许你将命令行应用程序与可理解数据... 查看详情

java自带的性能调优神器!!你还没用过吗?(代码片段)

点击关注公众号,实用技术文章及时了解VisualVM是Netbeans的profile子项目,已在JDK6.0update7 中自带,能够监控线程,内存情况,查看方法的CPU时间和内存中的对象,已被GC的对象,反向查看分配的堆栈(如10... 查看详情

sql工具sql调优和诊断神器sqltxplain(sqlt)简介(代码片段)

...计划、基于成本的OptimizerCBO统计信息、Schema对象元数据、性能统计信息、配置参数和会影响正在分析的SQL性能的其他元素。如果是SQL相关问题,建 查看详情

监控神器:prometheus轻松入门,真香!(代码片段)

点击关注公众号,实用技术文章及时了解导语:Prometheus是一个开源的完整监控解决方案,本文将从指标抓取到查询及可视化展示,以及最后的监控告警,对Prometheus做一个基本的认识。一、简介Prometheus是古希... 查看详情

监控神器:prometheus轻松入门,真香!(代码片段)

点击关注公众号,实用技术文章及时了解导语:Prometheus是一个开源的完整监控解决方案,本文将从指标抓取到查询及可视化展示,以及最后的监控告警,对Prometheus做一个基本的认识。一、简介Prometheus是古希... 查看详情

java性能分析神器-jprofiler详解(转)(代码片段)

前段时间在给公司项目做性能分析,从简单的分析Log(GClog,postgreplog, hibernate statitistic),到通过AOP搜集软件运行数据,再到PET测试,感觉时间花了不少,性能也有一定的提升,但总感觉像是工作在原始时代,无法简单顺... 查看详情

又一款全新的基于gpt4的python神器cursor,关键还免费(代码片段)

chartgpt大火之后,随之而来的就是一大类衍生物了。然后,今天要给大家介绍的是一款基于GPT4的新一代辅助编程神器——Cursor。它最值得介绍的地方在于它免费,我们可以直接利用它来辅助我们编程,真正做到事... 查看详情

又一款mybatis开发神器:fastmybatis太强大了!

点击关注公众号,实用技术文章及时了解fastmybatis是一个mybatis开发框架,其宗旨为:简单、快速、有效。零配置快速上手,无需编写xml文件即可完成CRUD操作。同时支持mysql、sqlserver、oracle、postgresql、sqlite。支持自... 查看详情

c#组件系列——又一款excel处理神器spire.xls(代码片段)

阅读目录一、组件介绍二、组件安装使用1、官方下载安装2、Nuget安装三、组件功能介绍1、Excel转PDF2、Excel生成图表3、其他功能介绍四、总结正文前言:最近项目里面有一些对Excel操作的需求,博主想都没想,NPOI呗... 查看详情

硬核:jvm性能调优,有哪些好用的内存分析神器?(代码片段)

...M内存优化是非常有必要的,可以提高系统的吞吐量和性能。通常调优的首选方式是减少FGC次数或者FGC时间,以避免系统过多地暂停。FGC达到理想值后,比如一天或者两天触发一次FGC。FCT时间优化为100~300毫秒后&#x... 查看详情

性能调优之三十六计——「取而代之」echo/json篇(代码片段)

...价值的提升至关重要!了解Go的同学知道,Echo是一款极易上手且广泛被使用或被使 查看详情

性能调优之三十六计——「取而代之」echo/json篇(代码片段)

...价值的提升至关重要!了解Go的同学知道,Echo是一款极易上手且广泛被使用或被使 查看详情