内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)
内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)
原文地址
https://zhanghan.blog.csdn.net/article/details/109255980
前言
最近刚上线了一款社交项目,运行十多天后(运营持续每天推量),发现问题:
系统OOM(资源不能被释放)导致服务器频繁且长时间FGC导致服务器CPU持续飚高
日志中内存溢出:java.lang.OutOfMemoryError: Java heap space
程序十分卡顿,严重影响用户使用
从以下方面,为大家分享此次问题解决流程
问题出现现象
临时解决方案
复现问题
定位问题发生原因
优化代码
优化后进行压测,上线
复盘
学完本博文,你的收获
排查内存溢出的思路
排查内存溢出过程中用到的命令及工具(Linux命令,Eclipse Memory Anaylzer[MAT])
定位系统内存溢出的代码,并进行优化
此次内存溢出问题复盘
解决方案流程图

问题&临时解决方案&定位问题&最终解决方案
问题:
业务反馈程序用的十分卡,同时测试自己测的也十分卡
从ELK收集的请求日志发现确实存在问题,线上是两台部署:两台机器上都是,一次请求耗时由原来的几毫秒变为10几秒
CPU跑的过高,当时是4核,CPU持续飙到350%+;
当时一台服务器CPU截图:
临时解决方案
当时为了减少对业务影响,直接将生产两台服务器上的项目进行重启
项目启动参数中没有加内存溢出日志输出(后续博客为大家介绍JVM调优时讲解启动命令中加内存溢出日志输出),重启后出问题时项目的JVM信息丢失了
复现问题方式:在开发环境对程序进行持续压测;压测相关服务器配置:
服务器配置:8核,16G
项目启动内存:136M
Jmeter持续(循环)压发消息接口10分钟
定位问题
top命令查看最耗CPU的进程(进程:17038;CPU持续飙到595%+)
top -H pid号,查看该进程中最耗CPU的线程(发现有一些线程占用CPU较高)

将线程号转为16进制,同时查看这些线程当前正在干什么(在此以17045线程为例)

可以看到最耗CPU的线程都是在进行GC
注意:
在FGC的时候会引起STW,所有应用都会短暂暂停,但是此时CPU仍然很忙,因为CPU在忙着进行FGC清理内存
用Jmap命令查看当前堆的使用情况(发现老年代现在已占用99.8%+)

查看gc 频率的命令(其中O代表老年代占用率,FGC是FullGC次数,FGCT是fullGC时间;可以看出在频繁FullGC但是老年代有资源一直释放不掉)

通过分析出问题时线上日志发现内存溢出;至此定位到问题根源是内存溢出导致(有未释放资源堆积,导致老年代被占满,然后频繁的FullGC但是资源一直释放不了)

分析问题产生原因
由于线上当时直接重启,未能保留当时的JVM内存文件;在开发环境进行循环压测,复现线上问题,然后导出dump文件进行分析找到原因
生成dump文件命令




分析代码
去代码中全局搜这两个类,发现只有在打日志的时候用到ClassClassPath类

分析ClassClassPath相关代码:
用到ClassClassPath对象是一个静态的ClassPool;
问题原因:classPath一直被静态的全局pool所持有,导致GC一直释放不掉;






优化代码:每次用完ClassClassPath后将其释放
每次对象使用完后从静态pool中移除
注意:classPath=null这种方式是不能释放掉的

优化后再次进行验证
开发环境循环压测,用MAT分析dump文件,发现内存中已不再堆积ClassClassPath类;优化前后接口吞吐量也提升8.2%
进行线上发布,观察一周后,对内存分析发现正常
复盘:
项目比对:
为快速开发,社交的代码从原来金融项目基础上改造而来;
原来金融项目没有内存溢出,而社交项目为什么内存溢出?
通过ELK统计一段时间的访问量结果:
社交目前日访问后台量65w+
金融项目只有4.5W+
社交和金融项目业务类型不一样,所呈现出的特点也不同
去生产的金融项目中dump内存文件,用MAT工具分析,发现也存在ClassClassPath类堆积释放不掉,只不过由于访问量少,堆积量未占满老年代而已;果断在金融项目迭代时将其优化;
程序预警:为减少业务影响,增加接口耗时的预警(后续博文为大家共享);实现方式:
- 在每次程序处理完进行预警(比如本次请求>阈值);缺点:消耗性能影响正常业务
- 在ELK清洗时用相关插件进行预警;优点:和业务解耦,对业务无影响
服务器预警:运维增加CPU内存,日志内存溢出监控
总结
解决内存溢出过程总结:
不同的项目导致内存溢出原因是不同的;
重要的是排查思路
经过不断的耐心的去观察,测试,分析才能定位到问题并最终解决问题
在这次分析内存溢出过程中,我们也针对我们项目的JVM启动参数进行了调优,在接下来的博文中为大家分享JVM调优
注意:
1,在FGC的时候会引起STW,所有应用都会短暂暂停,但是此时CPU仍然很忙,因为CPU在忙着进行FGC清理内存
2,使用jvisualvm来分析dump文件:
jvisualvm是JDK自带的Java性能分析工具,在JDK的bin目录下,文件名就叫jvisualvm.exe。
jvisualvm可以监控本地、远程的java进程,实时查看进程的cpu、堆、线程等参数,对java进程生成dump文件,并对dump文件进行分析。
原文地址
https://zhanghan.blog.csdn.net/article/details/109255980
内存溢出+CPU占用过高:问题排查+解决方案+复盘(超详细分析教程)的更多相关文章
- 性能优化-CPU占用过高问题排查
1. 性能优化是什么? 1.1 性能优化就是发挥机器本来的性能 1.2 性能瓶颈在哪里,木桶效应. CPU占用过高 1.现象重现 CPU占用过高一般情况是代码中出现了循环调用,最容易出现的情况有几 ...
- 一次java Cpu占用过高的排查
某一个项目CPU占用率一直很高,经常在40%-50%之间,最近比较闲,就开始了排查工作. 1.通过 jstack命令输出进程的堆栈信息 jstack 2788 >C:\log.txt 将堆栈信息 ...
- 使用ANTS Performance Profiler&ANTS Memory Profiler工具分析IIS进程内存和CPU占用过高问题
一.前言 最近一段时间,网站经常出现两个问题: 1.内存占用率一点点增高,直到将服务器内存占满. 2.访问某个页面时,页面响应过慢,CPU居高不下. 初步判断内存一点点增多可能是因为有未释放的资源一直 ...
- Java CPU占用过高问题排查,windows和Linux
LINUX系统: linux系统比较简单: 1.使用命令 ps -ef | grep 找出异常java进程的pid. 找出pid为 20189 2. top -H -p 20189,所有该进程的线程 ...
- 工具运行过程中,CPU占用过高的分析定位
之前使用Java Swing开发了一款设备档案收集工具.支持多台设备同时收集,每个设备使用一个线程.在同时收集多台设备信息时,发现CPU占用率居然达到了97%,而且高居不下.显然这样的性能是令人无法忍 ...
- 记一次用arthas排查jvm中CPU占用过高问题
记一次使用arthas排查jvm中CPU占用过高问题.这工具屌爆了 碾压我目前使用的全部JVM工具. 安装 小试 curl -O https://arthas.aliyun.com/arthas-bo ...
- java 一次CPU占用过高问题的排查及解决
最近一段时间 某台服务器上的一个应用总是隔一段时间就自己挂掉 用top看了看 从重新部署应用开始没有多长时间CPU占用上升得很快 排查步骤 1.使用top 定位到占用CPU高的进程PID ...
- Linux 内存 占用较高问题排查
Linux 内存 占用较高问题排查 niuhao307523005 2019-04-24 14:31:55 11087 收藏 11展开一 查看内存情况#按 k 查看 free #按兆M查看 free ...
- 【笔记】排查CPU占用过高
本文是该教程视频的笔记 https://www.bilibili.com/video/BV15T4y1y7eH 1. 问题演示 将演示项目打包放到服务器运行 执行 curl http://localh ...
- Linux系列---【内存占用过高问题排查思路】
内存占用过高问题排查思路 1.使用top命令查看后台任务 按shift+M使应用按内存使用率排序,定位到第一个使用内存最高的应用,并找到对应的PID. 2.使用ps命令查看对应的pid对应哪个应用 p ...
随机推荐
- 华为云大咖说:开发者应用AI大模型的“道、法、术”
本文分享自华为云社区<华为大咖说 | 企业应用AI大模型的"道.法.术" --道:认知篇>,作者:华为云PaaS服务小智. 本期核心观点 上车:AGI是未来5-10年内 ...
- 008. gitlab代码克隆与推送
推送配置 gitlab需要推送的客户端sshkey添加到gitlab服务器中 node1 推送配置 centos node1: [root@node1 ~]# cat ~/.ssh/id_rsa.pu ...
- zabbix笔记_001
zabbix介绍 zabbix是一个基于WEB界面的提供分布式系统监视以及网络监视功能的企业级的开源解决方案. zabbix能监视各种网络参数,保证服务器系统的安全运营:并提供灵活的通知机制以让系统管 ...
- NOIP模拟91(多校24)
T1 破门而入 解题思路 签到题(然而我数组开小直接变成暴力分...) 发现其实就是第一类斯特林数,然后 \(n^2\) 推就好了. 感觉可以用 NTT 优化成 \(nlogn\) ,但是好像并没有什 ...
- ansible搭建
ansible配置步骤 1.创建用户 2.用户提权 3.用户免密 4.cp ansible配置文件 5.配置主机清单 6.修改ansible 用户路径下的配置文件 1.创建用户(都要做) [root@ ...
- Android Media Framework(三)OpenMAX API阅读与分析
这篇文章我们将聚焦Control API的功能与用法,为实现OMX Core.Component打下坚实的基础. 1.OMX_Core.h OMX Core在OpenMAX IL架构中的位置位于IL ...
- .NET6 .NET CORE 使用Apollo
Apollo默认有一个"SampleApp"应用,"DEV"环境 和 "timeout" KEY. nuget 中下载 "Com. ...
- 学习ThreeJS
创建第一个应用 使用Three JS进行编程的时候,都是在调用new Three().XXX 来实现方法,让我们先根据官方文档创建一个demo https://threejs.org/docs/ind ...
- python 动态导入模块并结合反射,动态获取类、方法(反射太好用),动态执行方法
背景: 关键字驱动框架,不同的关键字方法分别定义在不同的类,真正执行关键字方法又在不同的类(简称A),这样就需要在执行前,要在文件A下import要使用的模块,如果有很多页面操作或很多模块时,就需要每 ...
- 基于 Cloudflare Workers 和 cloudflare-docker-proxy 搭建镜像加速服务
本文主要介绍了如何基于 Cloudflare Workers 和 cloudflare-docker-proxy 搭建 dockerhub.gcr.quay 等镜像加速服务. 最近,受限于各种情况,部 ...