性能分析-java程序篇之案例-工具和方法
1. 背景说明
线上服务响应时间超过40秒,登录服务器发现cpu将近100%了(如下图),针对此问题,本文说明排查过程、工具以定位具体的原因。

# 2. 分析排查过程
此类问题的排查,有两款神器可用,分别是async-profiler和arthas,async-profiler主要用于全局分析,通过此工具可以找到热点方法,
再用arthas对此热点方法进行详细的追踪,trace命令可以追踪方法的具体耗时,watch命令可以查看方法的出入参数,在结合源代码可以比较
方便定位到问题原因。下面记录排查过程:
## 2.1. 用async-profiler生成火焰图
到下载后,解压后如下所示:

执行命令生成火焰图:
./profiler.sh -d 300 1485 -f ./test.svg
其中 -d 300 表示采集300s的数据,300s结束后,自动生成test.svg文件到当前目录。
2.2. 火焰图分析
用浏览器打开上面生成的svg文件,如下:

火焰图中纵向代表调用栈,即方法的调用深度,横向是方法占用cpu的时间比率,因此火焰图中如果出现平顶现象,说明相关方法耗时长(即为热点方法),是分析优化的对象;
从上图可看出:java/util/ComparableTimSort.countRunAndMakeAscending方法为热点方法,可以根据此方法的调用栈对相关方法进行追踪:
io/micrometer/core/instrument/MeterRegistry.getMappedId
io/micrometer/core/instrument/Tags.and
2.3. 追踪方法具体耗时和调用关系
此时可采用arthas工具,改工具的安装和使用方法可参考:《arthas用户指南》
2.3.1. 追踪getMappedId
arthas控制台中执行下面命令:
trace io.micromete/core.instrument.MeterRegistry getMappedId

io.micrometer.core.instrument.MeterRegistry#getMappedId耗时近40s,期间此方法中调用了2458次MeterFilter.map()方法: 该方法源代码如下:

通过多次执行该命令发现,filters数组会随着请求增加而不断上涨;那么这个filters数组到底是什么内容呢?
2.3.2. 监控类的返回对象
watch *MeterRegistry * "{returnObj}" -x 3 -n 3

发现数组中储存的都是相同内容的tag,继续查看源代码,io.micrometer.core.instrument.MeterRegistry类中成员变量赋值的相关代码:

2.3.3. 监控Tags and方法的入参
watch io.micrometer.core.instrument.Tags and "{params}" -x 2 -b -n 4

2.4. 原因
commonTags每调用一次,filters数组长度+1,会进行一次copy,不断增长,getMappedId方法中循环对tag进行and操作、排序、去重导致cpu飙高;
下面是导致这个问题原因精简后的模拟代码:

2.5. 解决方式
commonTags应在服务初始化的时候设置,如在spring boot的配置文件中设置:

性能分析-java程序篇之案例-工具和方法的更多相关文章
- 利用jdk自带的运行监控工具JConsole观察分析Java程序的运行
利用jdk自带的运行监控工具JConsole观察分析Java程序的运行 原文链接 一.JConsole是什么 从Java 5开始 引入了 JConsole.JConsole 是一个内置 Java 性能 ...
- 【转】一文掌握 Linux 性能分析之网络篇
[转]一文掌握 Linux 性能分析之网络篇 比较宽泛地讲,网络方向的性能分析既包括主机测的网络配置查看.监控,又包括网络链路上的包转发时延.吞吐量.带宽等指标分析.包括但不限于以下分析工具: pin ...
- 【转】一文掌握 Linux 性能分析之内存篇
[转]一文掌握 Linux 性能分析之内存篇 前面我们已经学习了 CPU 篇,这篇来看下内存篇. 01 内存信息 同样在分析内存之前,我们得知到怎么查看系统内存信息,有以下几种方法. 1.1 /pro ...
- 一文掌握 Linux 性能分析之网络篇
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 这是 Linu ...
- 鸿蒙内核源码分析(编译过程篇) | 简单案例窥视GCC编译全过程 | 百篇博客分析OpenHarmony源码| v57.01
百篇博客系列篇.本篇为: v57.xx 鸿蒙内核源码分析(编译过程篇) | 简单案例窥视编译全过程 | 51.c.h.o 编译构建相关篇为: v50.xx 鸿蒙内核源码分析(编译环境篇) | 编译鸿蒙 ...
- 【转】一文掌握 Linux 性能分析之网络篇(续)
[转]一文掌握 Linux 性能分析之网络篇(续) 在上篇网络篇中,我们已经介绍了几个 Linux 网络方向的性能分析工具,本文再补充几个.总结下来,余下的工具包括但不限于以下几个: sar:统计信息 ...
- 【转】一文掌握 Linux 性能分析之 CPU 篇
[转]一文掌握 Linux 性能分析之 CPU 篇 平常工作会涉及到一些 Linux 性能分析的问题,因此决定总结一下常用的一些性能分析手段,仅供参考. 说到性能分析,基本上就是 CPU.内存.磁盘 ...
- 一文掌握 Linux 性能分析之网络篇(续)
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 这是 Linu ...
- 如何利用JConsole观察分析Java程序的运行并进行排错调优_java
如何利用JConsole观察分析Java程序的运行并进行排错调优_java 官方指导 use jconsole use jmx technology
随机推荐
- ==和equals的深度分析
==的分析 1.对于基本数据类型,比较的是他们的具体内容是不是一样,跟他们的内存地址无关.举个栗子: public class Test{ public static void main(String ...
- Flume理论研究与实验
一.理论研究 1.1 总览 Flume是一个分布式的可靠的日志收集系统,主要是用于从各种数据源收集.聚合并移动大批量的日志数据到存储系统:它本身具有许多故障转移和恢复机制,具有强大的容错能力:它使用下 ...
- webpack学习2.3webpack核心概念
核心概念(四个) Entry(入口) Output(出口) Loaders()来处理其他类型的资源文件 Plugins(插件) 1.入口(Entry) 作用:代码的入口,打包的入口,单个或多个, 示例 ...
- 《Java练习题》进阶练习题(五)
编程合集: https://www.cnblogs.com/jssj/p/12002760.html 前言:不仅仅要实现,更要提升性能,精益求精,用尽量少的时间复杂度和空间复杂度解决问题. [程序88 ...
- LImax服务器框架学习--安装、使用ant工具、生成limax相关代码
一.安装ant ant 是一个将软件编译.测试.部署等步骤联系在一起加以自动化的一个工具,大多用于Java环境中的软件开发.在实际软件开发中,有很多地方可以用到ant. 首先现在一个ant安装压缩包, ...
- 比较typeof与instanceof
相同点: JavaScript中typeof和instanceof常用来判断一个变量是否为空,或者是什么类型的. 不同点: typeof的定义和用法: 返回值是一个字符串,用来说明变量的数据类型. 细 ...
- Poco的介绍和入门教学
版权声明:该文章为AirtestProject原创文章:允许转载,但转载必须注明“转载”并保留原链接 前言 前面我们已经介绍了基于图像识别的测试框架Airtest,通过图像识别,已经可以编写大部分的测 ...
- CTF KFIOFan: 2 Vulnhub Walkthorugh
主机扫描: ╰─ nmap -p- -A 10.10.202.152 Starting Nmap 7.70 ( https://nmap.org ) at 2019-08-29 16:55 CSTNm ...
- Android 进度对话框 ProgressDialog
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentV ...
- 13-Node.js学习笔记-MongoDB
数据库相关概念 在一个数据库软件最终可以包含多个数据仓库,在每个数据仓库中可以包含多个数据集合,每个数据集合中可以包含多条文档(具体的数据) database: 数据库,mongoDB数据库软件中可以 ...