Java应用性能问题诊断技巧
作者:张彦东
参考:https://developer.aliyun.com/ebook/450?spm=a2c6h.20345107.ebook-index.28.6eb21f54J7SUYc
文章目录
- (一)内存
- 1.内存
- 2.内存-JMX
- 3.内存-Jmap
- 4.内存-结合代码确认问题
- (二)CPU
- 1.CPU-JMX或Jstack
- 2.CPU-Async-Profiler
- (三)网络
- 1.常用命令
- 2.TCP状态机
- 3.TCP状态说明
- 4.实战的场景
应用性能问题的诊断主要从以下三方面入手:内存、CPU、网络。
(一)内存
1.内存
·现象
1)OutOfMemoryError: Java heap space;
2)频繁FULL GC;
·原因
1)内存泄露;
2)堆大小配置不合理;
·解决方法
1)jvisualvm;
2)jstat;
3)jmap;
4)mat。
java.lang.OutOfMemoryError: Java heap spaceat java.util.Arrays.copyOfRange(Arrays.java:3664) ~[na:1.8.0_271]at java.lang.StringBuffer.toString(StringBuffer.java:669) ~[na:1.8.0_271]at com.aliyun.javards.controller.MyController.genString(MyController.java:74) ~[classes!/:0.0.1-SNAPSHOT]at com.aliyun.javards.controller.MyController.leakMem(MyController.java:63) ~[classes!/:0.0.1-SNAPSHOT]at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_271]

如上图所示,这段日志是当出现内存耗尽的时候,结果会报出来一些错误,应用会出现频繁的FULL GC。
2.内存-JMX

诊断结内存的问题的方法:
可以打开JMX通过启动参数以-D开头这4个参数进行远程连接,连接之后可以看到最大堆的大小以及实际已经使用的情况。
3.内存-Jmap
同时通过JMX对堆进行一个Dump,文件会在Jvm运行所在主机的对应的目录上。

第二种是 jmap -heap 2780进程号,可以看到Jmap的堆的最大大小是512兆,同时看到老年代的使用情况是78%。通过命令把Jmap的堆内存Dump到文件中做后续分析。通过命令提示正在进行Dump,完成后会有一个Heap Dump File Created日志。
用MAT打开堆的Dump文件,然后用内存泄露分析模式,通过结果可以看到 Controller里面有大量的对象,MAT的下载地址https:/www.eclipse.org/mat/。
4.内存-结合代码确认问题
确认最终的问题,打开MAT打开堆的Dump文件之后,通过内存泄露的分析,可以找到MyController下的list对象,里面存在大量字符串,每个字符串的大小约为2M,大概有100个,占用了268兆,可以看到具体的字符串的内容。
结合代码,看到在代码中第63行申请了一个1M长度,2M字节大小的内存,并且把内存放到一个全局的静态变量中进行应用,所以GC无法回收,因为是一个强引用无法回收,否则将导致内存泄漏。
通过Jmap把堆Dump出来,再通过MAT工具对内存进行分析,找到占用内存的对象,再通过对象里的一些引用关系,就能够找到代码里面创建对象,找到出现问题的代码,完成内存泄露的定位。

(二)CPU
CPU问题定位:
·现象
1)应用响应缓慢;
2)Java进程CPU占用高;
·原因
1)存在大量消耗CPU的逻辑;
2)循环;
3)复杂计算;
·解决方法
1)Top;
2)Jvisualvm ;
3)Async-profiler;
1.CPU-JMX或Jstack

如上图所示案例,一个一核的主机,CPU使用率接近100%,主机的负载达到了6点多,Java进程的CPU使用率可以到99%,通过选择JMX或者Jstack。

JMX连上去之后去检查每个线程是否在执行,这里通过JMX可以看到线程池1里的线程号1~6在长期的运行,因此这可能就是问题线程。
同时可以通过Jstack查看Jvm里面每个现场的堆栈,但是通过Jstack有一个缺点就是当应用里面线程非常多的时候,Jstack的结果会非常大,难以分析。
2.CPU-Async-Profiler
下载对应平台已编译好的代码,解压后找到对应的Java进程,通过这一串命令,对Java进程做一个系统剖析,剖析完之后会生成一个火焰图,通过火焰图能够准确地看到应用的热点代码。
tar -xf async-profiler-1.8.3-linux-x64.tar.gz
cd async-profiler-1.8.3-linux-x64
./profiler.sh -e itimer -d 10 -f /share/cpu-flame-graph.svg --title "CPU profile"
3141
这里对上列参数做一个说明:
增加了-e itimer后,会不依赖perf_events,只剖析JVM一般就够了;
-d 10 表示剖析持续10秒,可以根据实际情况调整;
最后的3141是Java进程的pid。

通过生成的火焰图之后,用浏览器打开可以看到里面有6个线程长期霸占CPU。火焰图从上往下看,下面的方法是处于栈底的,上面的方法是属于栈顶的,栈顶的方法就是正在执行的方法,而栈顶上面的最宽的方法就是占用CPU最多的方法,所以可以看到这里有6个线程,里面有6个栈,每个栈上都正在执行方法在消耗CPU。

结合上图代码,通过堆栈来对应到源码。可以看到,通过JMX可以找到可疑的线程,通过Async-profiler可以生成火焰图,直接定位到存在性能问题的线程以及它的堆栈,通过堆栈就用源码找到真正有问题的代码。
(三)网络
1.常用命令
网络问题包含以下常用命令:
1)查看当前主机IP:ip a
2)查看当前主机名:hostname
3)检查目标IP是否可达:ping
4)检查目标端口是否可达:telnet
5)查看网卡:ifconfig
6)查看路由表:route –n
7)查看从当前主机发往目标主机中间会经过哪些路由:traceroute –i
8)查看当前主机的网卡流量:iptraf-ng
9)查看以IP为单位的网络流量排名:iftop –n
10)查看当前主机上监听的端口:netstat –tpnl
11)查看当前主机上的TCP连接:netstat –tpn
2.TCP状态机

TCP状态机是TCP连接的核心部分,只有深入理解TCP状态机,才能灵活运用TCP的命令与工具,以及理解输出的结果与意义。
3.TCP状态说明
CLOSED:表示当前连接已经关闭。
LISTEN:表示当前正监听中,随时准备接受连接请求。
SYN_SENT:表示已经发送出建立TCP连接的数据包,等待对方回应。
SYN_RECVD:表示接受到了建立TCP连接的数据包,准备给对方发送SYN + ACK。
ESTABLISHED:表示已经建立TCP连接。
FIN WAIT-1:表示主动关闭连接的一方已经发出了FIN包。
CLOSE WAIT:表示被动关闭的一方收到了FIN包。
FIN WAIT-2:表示主动关闭的一方收到了FIN的ACK包,等待对方发出的 FIN包。
LAST ACK:表示被动关闭的一方发出了FIN包,开始等待对方发出ACK。
TIMED WAIT:表示主动关闭的一方已经发出了ACK,此时主动关闭的一方要等待2倍Maximum segment lifetime,在此期间,任何因为网络延迟或者拥堵而未及时到达的包将会被丢弃,以防止下一个连接收到了上一个连接的包。
4.实战的场景
a.配置问题引起的应用阻塞

现象是一段Python(其它语言相同)程序会阻塞,应用僵死。
诊断:
netstat-tpn|grep python
tcp 0 1
10.0.3.15:41570 192.168.1.1:80 SYN_SENT 15349/python
2.7
可以看到Python程序在等待主机192.168.1.1的ACK,而这个主机根本就不存在因此无法访问。再结合目标端口是80,定位到是程序HTTP请求的目标主机错误。
b.某个数据库的连接数暴涨,想查到连接来源
netstat -tpn|grep 3310|grep -i estab|awk '{print $4}'|cut -d ':'
-f 1|awk '{a[0]=a[0]=a[0] + 1} END {for (i in a) print i " " a[i]}'
10.0.3.15 999
可以看到,来自10.0.3.15的连接数达到了999个,结合代码就可找到问题。
c.线上应用没有打印SQL到日志中,DB也没有开审计日志,如何能看到SQL信息?
命令:tcpdump -i any port 3310 -tttt -nn -A -s0
2020-09-18 17:58:21.284833 IP 11.193.115.110.56454 > 11.193.115.110.3310: Flags
[P.], seq 1313:1606, ack 1238, win 6360, options [nop,nop,TS val 400339442 ecr
400339440], length 293
....E..Y..@.@.....sn..sn........u..............
........!.... select cu.id from test_table cu where cu.ins_name = 'yunji-ddr12' and
cu.is_deleted = 0 and ((cu.ins_type in (0, 2, 20) and cu.is_tmp = 0) or (cu.ins_type = 1
and cu.parent_id > 0)) and cu.status in (0,, 35, 36)
可以在应用服务器执行tcpdump,-i any表示监听任意网卡,port 3310表示去dump 3310端口,-tttt表示在每个包前面增
加一个时间戳,-nn表示不对端口和IP进行反向域名解析,-A表示以应用层的方式输出日志,-s0表示Buffer的控制。
通过这个命令,从网络上可以清晰的看到真实的SQL语句,这对于排查问题非常有帮助。
d.传说中的TCP3次握手和4次挥手,到底是什么样
命令:tcpdump -i any port 3310 -tttt -nn -X -s0

如上图所示,用户还可以通过Tcpdump来查看3次握手和4次挥手的网络数据。上图最上方三个包就是我们说的三次握手,它能够去建立TCP连接,建立成后MySQL会向客户端发送提示输入密码的文字,同时客户端会向MySQL客户端发送一个响应,表示收到数据包。
如果这个时候关闭连接就会产生4次挥手,分别是用户客户端向MySQL端发送一个关闭连接包文,MySQL会马上响应一个ACK,同时发出一个关闭连接包文,用户客户端也向MySQL响应一个ACK,这就是传说中TCP的3次握手和4次挥手。
如上图所示,用户还可以通过Tcpdump来查看3次握手和4次挥手的网络数据。上图最上方三个包就是我们说的三次握手,它能够去建立TCP连接,建立成后MySQL会向客户端发送提示输入密码的文字,同时客户端会向MySQL客户端发送一个响应,表示收到数据包。
如果这个时候关闭连接就会产生4次挥手,分别是用户客户端向MySQL端发送一个关闭连接包文,MySQL会马上响应一个ACK,同时发出一个关闭连接包文,用户客户端也向MySQL响应一个ACK,这就是传说中TCP的3次握手和4次挥手。
相关文章:
Java应用性能问题诊断技巧
作者:张彦东 参考:https://developer.aliyun.com/ebook/450?spma2c6h.20345107.ebook-index.28.6eb21f54J7SUYc 文章目录 (一)内存1.内存2.内存-JMX3.内存-Jmap4.内存-结合代码确认问题 (二)CPU1.CPU-JMX或…...
监控系列(六)prometheus监控DMHS操作步骤
一、监控的操作逻辑 给操作系统安装expect命令expect脚本执行dmhs_console脚本执行 cpt / exec 命令用脚本进行过滤字符串过滤dm_export读取脚本与当前日期作比较,然后返回差值 二、安装步骤 1. linux中Expect工具的安装及使用方法 https://blog.csdn.net/wangta…...
SLAM从入门到精通(dwa速度规划算法)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 要说搜路算法,这个大家都比较好理解。毕竟从一个地点走到另外一个地点,这个都是直觉上可以感受到的事情。但是这条道路上机…...
嵌入式实时操作系统的设计与开发(aCoral线程学习)
真正的RTOS,基本上没有做到进程,只是停留在多线程,因为多进程要解决很多问题,且需要硬件支持,这样就使得系统复杂了,从而就可能影响系统实时性。 线程之间是共享地址的,也就是说当前线程的地址…...
JAVA基础(JAVA SE)学习笔记(二)变量与运算符
前言 1. 学习视频: 尚硅谷Java零基础全套视频教程(宋红康2023版,java入门自学必备)_哔哩哔哩_bilibili 2023最新Java学习路线 - 哔哩哔哩 正文 第一阶段:Java基本语法 1. Java 语言概述 JAVA基础(JAVA SE)学习…...
chatgpt 接口 和 jupyter版本安装
一 接口代码 有时间继续测试 import openai # 填入你的api_key openai.api_key ""models openai.Model.list()# 定义API参数 params {role: "user", "content": }# 定义循环 while True:# 获取用户输入user_input input("请输入您的消…...
ubuntu20.04 nerf开山之作
源码 GitHub - yenchenlin/nerf-pytorch: A PyTorch implementation of NeRF (Neural Radiance Fields) that reproduces the results. 代码的相关解读 NeRF代码解读-相机参数与坐标系变换 - 知乎 原文题目:NeRF: Representing Scenes as Neural Radiance Field…...
Java 中实现单例模式
单例模式 单例模式,就是一个类在任何情况下绝对只有一个实例,并且提供一个全局访问点来获取该实例。 要实现单例,至少需要满足两个点: 私有化构造方法,防止被外部实例化造成多实例问题 提供一个静态方位作为全局访问点…...
标签页的使用
目录 1、引用TabSheet.h和TabSheet.cpp文件: 2、主窗口添加标签页: (1)、标签页的创建和属性更改 (2)、添加俩个标签页的类 (3)、主窗口添加成员变量 (4)…...
新一代开源语音库CoQui TTS冲到了GitHub 20.5k Star
Coqui TTS 项目介绍 Coqui 文本转语音(Text-to-Speech,TTS)是新一代基于深度学习的低资源零样本文本转语音模型,具有合成多种语言语音的能力。该模型能够利用共同学习技术,从各语言的训练资料集转换知识,来…...
CSS 效果:多列文字,第一行对齐,flex方式元素被挤压
如图效果:2列,第一列只有一行,第二列多行。要求第一行对齐 实现:使用flex 如果不配置flex-shrink的话,第一列会被挤压 给第一列:备注配置压缩属性: flex-shrink:0。 <!DOCTYPE…...
优维低代码实践:片段
优维低代码技术专栏,是一个全新的、技术为主的专栏,由优维技术委员会成员执笔,基于优维7年低代码技术研发及运维成果,主要介绍低代码相关的技术原理及架构逻辑,目的是给广大运维人提供一个技术交流与学习的平台。 优维…...
【计算机网络】第一章、计算机网络体系结构
1.1计算机网络的组成与分类 1.计算机网络的组成 从不同的角度来看内容从组成上看硬件、软件、协议从工作方式上岸边缘部分、核心部分从功能上看通信子网、资源子网 2.计算机网络的分类 角度内容分布范围广域网、城域网、局域网、个域网传输技术广播式网络、点对点网络拓扑结…...
vr火灾逃生安全科普软件开展消防突击教育安全有效
VR火灾逃生自救虚拟体验是一种利用虚拟现实技术来模拟火灾逃生自救场景的教育工具。以下是这个体验的几个优点:VR消防安全体验馆的出现,为城市的安全教育开辟了新的途径。这种创新的体验方式,能够让市民在模拟的火灾场景中学习并掌握消防安全…...
Kafka SASL认证授权(五)ACL源码解析
Kafka SASL认证授权(五)ACL源码解析。 官网地址:https://kafka.apache.org/ 一、ACL检查流程解析 一起看一下kafka server的启动与监听流程: Kafka -> KafkaServer -> SocketServer、KafkaRequestHandler 其中KafkaServer做相关的初始化,包括SocketServer 与 han…...
logback-spring.xml 中根据不同的业务表示,分类打印到不同的文件夹、时区动态设置
logback-spring.xml 中根据不同的业务表示,分类打印到不同的文件夹、时区动态设置 logback-spring.xml 完整配置 <?xml version"1.0" encoding"UTF-8"?> <configuration debug"false" scan"true" scanPeriod&…...
linux系统编程之一
1)fcntl的使用方法 fcntl作用:可以用fcntl函数改变一个已打开的文件属性而不必重新打开文件; 堆排序是完全二叉树,但不是排序二叉树; 排序二叉树要求兄弟节点之间有大小关系,比如说左小右大; 堆排序仅要求…...
【LeetCode】《LeetCode 101》第十三章:链表
文章目录 13.1 数据结构介绍13.2 链表的基本操作206. 反转链表(简单)21. 合并两个有序链表(简单)24.两两交换链表中的节点(中等) 13.3 其它链表技巧160. 相交链表(简单)234. 回文链表…...
Electron webview 内网页 与 preload、 渲染进程、主进程的常规通信 以及企业级开发终极简化通信方式汇总
Electron 嵌入的页面中注入的是 preload.js 通过在标签中给 prelaod赋值,这里提到了 file://前缀,以及静态目录 static 怎么获取 实际代码,其中__static就是我们存放静态文件的地方,这个 static 是 electron 源代码根目录下的文件…...
AI人工训练师,提升外呼机器人的运营效果
外呼机器人是企业客服和营销的重要工具,外呼机器人可以通过语音识别和语音合成技术,自动拨打电话并进行客户服务和营销推广等工作。由于外呼机器人错误识别和理解偏差容易影响外呼效果,许多外呼机器人厂商选择通过AI人工训练师的技术手段来提…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
三维GIS开发cesium智慧地铁教程(5)Cesium相机控制
一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点: 路径验证:确保相对路径.…...
边缘计算医疗风险自查APP开发方案
核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...
ssc377d修改flash分区大小
1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...
