实战JVM高CPU、内存问题分析定位

背景:

业务中台组件MOSC开展压测工作,并发场景下发现CPU使用率达到100%,虽然程序没有报错,但是这种情况显然已经达到性能瓶颈,对服务带来了验证的效能影响,所以针对该CPU问题必须进行详细的根因分析处理。

这次针对分析过程做了详细的记录,希望给大家在日常工作中,遇到CPU和内存问题能高效准确的进行分析定位。

一、通过监控确定问题

应用研发这边可以通过Grafana监控观察相关资源使用情况:

这里可以看到CPU已经达到99%以上,已经达到了瓶颈。

二、CPU问题分析

1、进入容器查看当前CPU占比最高的进程信息

使用TOP命令查看,可以发现确实是因为mosc服务导致

2、定位占用CPU最高的具体线程,可以使用TOP -H -p pid指令查看

3、通过jvm指令查看当前线程栈信息,jstack  -l  pid  |  grep  nid  -A  50

 注:

jstack信息中记录nid是16进制,需要将当前线程ID转成16进制

jstack是在容器中打印栈信息,正常情况下建议通过jmap导出dump文件然后进行搜索定位,避免jstack指令给当前执行服务造成影响。

这里发现已经搜索定位到了nid为89的线程栈信息,注意当前线程是VM Thread,大概率推测当前线程是GC线程。

注:如果是正常的请求线程,这里就可以通过栈信息定位到具体的程序,例如上图的nid=0x92。

4、检查GC情况

使用jstat -gcold 85 1000 ,查看Old区GC和内存实时状态。大致的可以看出来,Old区使用率已经100%了,FULLGC非常的频繁,差不多5秒一次。

  1. 查看GC原因

使用jsta  -gccause  85 1000指令,查看当前GC实时情况包括原因。

这里可以看出来频繁的FULLGC原因都是相同的Allocation Failure,无法分配资源。

其实到此,基本上已经可以测出来一些结论了:

压测过程中虚拟机内存吃满无法分配资源,导致频繁的FULLGC而占用过多的CPU资源。所以程序执行过程中可能产生了大数据量,导致了大对象的诞生,根据Jvm内存分配原理,大对象会直接放入到Old区,并发场景下Old区很快就会被大对象吃满,从而引发FGC。

三、内存占用分析

1、导出dump日志信息

针对内存分析,最好的方式的就是导出dump快照文件,借助工具来分析,比如MAT、Jvisualvm、Jprofile等,我这里使用的就是Jprofile。

使用jmap -dump:live,format=b,file=/路径/dump.hprof  85 指令导出dump文件。

2、分析内存情况

使用Jprofile打开dump文件

可以看出来这里存在这比较大的实例,选择String实例看下引用情况,

这个可以知道当前实例最终的引用来自于ArrayList对象。

3、查看大对象试图

Jprofile提供了BiggestObjects视图,可以观察当前内存中的大对象

这里可以看到和上面分析的一样,确实存在这ArrayList大对象,继续查看当前对象的引用信息

到此就已经可以定位到了大致的程序了:GetWorkService.getWork#doGetPageWork#WoList().select()

当前select方法是数据库调用方法,所以结合前面分析的内容,可以推测当前程序可能获取到了大数据量信息,并使用了ArrayList对象接收。

四、结合请求日志定位具体程序问题和优化

既然已经清楚了大致的程序和原因,那就可以按照这个思路具体的验证和程序分析了

1、内存占用验证

关闭其他的API脚本,只启动当前API观察内存使用情况。

这里可以看到执行了一次API后,Old区上升了约350m,正如上面我们推测的,当前API产生了大对象,直接放入到Old区,并发后导致内存吃满。

2、结合pinpoint链路分析具体SQL

因为清楚了问题API和大致的程序,我们跟容易就可以通过pinpoint分析到具体的执行SQL。

通过测试执行该SQL,发现当前SQL会读取出来约7w数据量,以及约120个栏位信息。

3、结合程序分析优化

结合当前程序分析后发现,当前API虽然支持分页查询,但是在获取total时,使用原SQL查询所有数据,然后获取size,导致了获取到了7w多笔数据,导致了效能问题。

到此全部的问题都已经分析完了,接下来就是联系PR做优化调整了,获取total直接通过select count获取总数total。

4、结果验证

再PR程序调整后,验证结果。现在继续压测当前API使用10U并发(之前是跑一次,消耗300mb内存占用)

耗时结果对比:从之前100s降到了1秒多

内存对比:现在10U下,内存几乎没有浮动

CPU对比:现在max CPU是40%左右

搞定!

PS:

大数据问题往往是导致CPU、内存问题最主要原因之一,造成的影响可能是服务级别,所以日常开发过程中,在非业务需求场景下,尽量减少内存数据量,避免导致资源问题和效能风险。

对于上述分页场景中需要获取总数total,后续也会纳入应用开发规范要求:分页场景下获取数据总数,使用统计函数获取,例如select count,禁止获取全部数据,在内存获取size。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/211121.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

redis实现分布式锁

实现分布式锁时需要实现的两个基本方法: 获取锁: 互斥:确保只能有一个线程获取锁非阻塞:尝试一次,成功返回true,失败返回false 释放锁: 手动释放超时释放:获取锁时添加一个超时时间…

unordered_map 与 unordered_set 的使用

unordered_map unordered_map 的介绍文档 unordered_map 的介绍文档&#xff1a;来自cpluscplus.com 的中文翻译 unordered_map是存储<key, value>键值对的关联式容器&#xff0c;其允许通过keys快速的索引到与 其对应的value。在unordered_map中&#xff0c;键值通常用…

OpenWRT软路由web界面如何远程访问

文章目录 1.openWRT安装cpolar2.配置远程访问地址3.固定公网地址 简单几步实现在公网环境下远程访问openWRT web 管理界面&#xff0c;使用cpolar内网穿透创建安全隧道映射openWRT web 界面面板443端口&#xff0c;无需公网IP&#xff0c;无需设置路由器。 1.openWRT安装cpola…

解决:前端js下载文件流出现“未知文件格式”错误

第一中情况&#xff1a; 出现的问题&#xff0c;前端已经设置了responseType: blob,下载下来还是格式不对。 最后经过排查&#xff0c;后端缺少charsetutf-8&#xff0c;所以前端可以设置编码&#xff1a; 第二中情况&#xff1a; 后端已经设置了charsetutf-8&#xff0c;前…

【Java】认识String类

文章目录 一、String类的重要性二、String类中的常用方法1.字符串构造2.String对象的比较3.字符串查找4.转换5.字符串替换6.字符串拆分7.字符串截取8.其他操作方法9.字符串的不可变性10.字符串修改 三、StringBuilder和StringBuffer 一、String类的重要性 在C语言中已经涉及到…

leetcode (力扣) 97. 交错字符串(动态规划)

文章目录 题目描述思路分析完整代码 题目描述 给定三个字符串 s1、s2、s3&#xff0c;请你帮忙验证 s3 是否是由 s1 和 s2 交错 组成的。 两个字符串 s 和 t 交错 的定义与过程如下&#xff0c;其中每个字符串都会被分割成若干 非空 子字符串&#xff1a; s s1 s2 … sn t …

tp8 使用rabbitMQ(1)简单队列

php8.0 使用 rabbitmq 要使用 3.6版本以上的&#xff0c; 并且还要开启 php.ini中的 socket 扩展 php think make:command SimpleMQProduce //创建一个生产者命令行 php think make:command SimpleMQConsumer //创建一个消费者命令行 代码中的消息持久化的说明 RabbitMQ 消息持…

登陆页面模板

简单好看的登陆页面 vue项目代码 可忽略js部分 先来个效果图 <template><div class"login"><div class"content"><p >账户密码登录</p><div class"unit"><label class"label">用户名</…

Linux-权限

1.Shell命令以及运行原理 Linux 严格意义上说的是一个操作系统&#xff0c;我们称之为 “ 核心&#xff08; kernel &#xff09; “ &#xff0c;但我们一般用户&#xff0c;不能直接使用 kernel 。而是通过kernel 的 “ 外壳 ” 程序&#xff0c;也就是所谓的 shell &#x…

DLL劫持漏洞

以下是自己学习时做的一些笔记&#xff0c;希望对各位有所帮助 DLL劫持漏洞 为什么程序中会有dll的存在 对于 Windows 操作系统&#xff0c;操作系统的大部分功能都由 DLL 提供。 另外&#xff0c;当您在这些 Windows 操作系统之一上运行某一程序时&#xff0c;该程序的很多…

Python语言:猜数字游戏案例讲解

猜数字游戏题目要求如下&#xff1a;该程序随机生成一个1到100之间的整数&#xff0c;然后要求玩家在有限的次数内猜出这个数字。如果玩家猜对了&#xff0c;游戏结束并显示成功信息&#xff1b;如果玩家猜错了&#xff0c;程序会提示玩家猜的数字是偏大还是偏小&#xff0c;并…

最新版灵沐V3.3微信资源类小程序源码支持流量主

源码简介 最新版灵沐V3.3微信资源类小程序源码支持流量主&#xff0c;一套不错的流量主变现资源下载小程序&#xff0c;它支持在微信、QQ和抖音平台上运行。这次更新主要集中在全局UI设计的升级&#xff0c;并依然注重资源下载和激励视频变现的功能。另外&#xff0c;还新增了…