青少年白癜风援助平台 http://www.xftobacco.com/前言
最近刚上线了一款社交项目,运行十多天后(运营持续每天推量),发现问题:系统OOM(资源不能被释放)导致服务器频繁且长时间FGC导致服务器CPU持续飚高日志中内存溢出:java.lang.OutOfMemoryError:Javaheapspace程序十分卡顿,严重影响用户使用从以下方面,为大家分享此次问题解决流程问题出现现象临时解决方案复现问题定位问题发生原因优化代码优化后进行压测,上线复盘学完本博文,你的收获
排查内存溢出的思路排查内存溢出过程中用到的命令及工具(Linux命令,EclipseMemoryAnaylzer[MAT])定位系统内存溢出的代码,并进行优化此次内存溢出问题复盘
解决方案流程图
Java从入门到项目实战淘宝¥49.8¥79.8购买已下架
问题临时解决方案定位问题最终解决方案
问题:
业务反馈程序用的十分卡,同时测试自己测的也十分卡从ELK收集的请求日志发现确实存在问题,线上是两台部署:两台机器上都是,一次请求耗时由原来的几毫秒变为10几秒CPU跑的过高,当时是4核,CPU持续飙到%+;当时一台服务器CPU截图:
临时解决方案
/p>
当时为了减少对业务影响,直接将生产两台服务器上的项目进行重启项目启动参数中没有加内存溢出日志输出(后续博客为大家介绍JVM调优时讲解启动命令中加内存溢出日志输出),重启后出问题时项目的JVM信息丢失了
复现问题方式:在开发环境对程序进行持续压测;压测相关服务器配置:
服务器配置
核,16G项目启动内存:MJmeter持续(循环)下发消息接口10分钟
定位问题
top命令查看最耗CPU的进程(进程:;CPU持续飙到%+)#输入top命令后键入P(大写P),进程按照CPU从高到底排序top
查看该进程中最耗CPU的线程(发现有一些线程占用CPU较高)#为进程号,键入P(大写P),该进程中的线程按照CPU从高到底排序top-Hp
将线程号转为16进制,同时查看这些线程当前正在干什么(在此以线程为例)#将线程号转为16进制;其中为线程号printf%x\n#为进程号,0x为最耗CPU线程的十六进制jstack
grep0x-C10--color
可以看到最耗CPU的线程都是在进行GC用Jmap命令查看当前堆的使用情况(发现老年代现在已占用99.8%+)#其中为进程号jmap-heap
查看gc频率的命令(其中O代表老年代占用率,FGC是FullGC次数,FGCT是fullGC时间;可以看出在频繁FullGC但是老年代有资源一直释放不掉)#其中为进程号,是指每5秒(毫秒)输出一次jstat-gcutil
通过分析出问题时线上日志发现内存溢出;至此定位到问题根源是内存溢出导致(有未释放资源堆积,导致老年代被占满,然后频繁的FullGC但是资源一直释放不了)grep-m10OutOfMemoryError*.log
分析问题产生原因
由于线上当时直接重启,未能保留当时的JVM内存文件;在开发环境进行循环压测,复现线上问题,然后导出dump文件进行分析找到原因生成dump文件命令#其中fileName是导出后dump名称,pid为进程号jmap-dump
ormat=b,file=fileName.dumppid将dump文件导出到本地,用EclipseMemaryAnalysis(MAT