泛微应用 v9企业版部署的应用内存溢出,造成服务器宕机假象
由 he shancai 在 超过 3 年 之前添加
出现场景:客户使用中间件运行应用,运行过程中,用户发送请求长期无响应,过程大概持续两小时后,服务器恢复正常
出现时间:2021/10/19 11:30左右
操作系统信息:云服务器,麒麟v10版本
解决过程:
1、捕抓堆栈信息:
jstack 进程号>/home/jstack01.txt (捕抓堆栈日志时机为正在发生第一时间,确保信息准确)尽可能捕抓多个堆栈日志快照日志(3-10个)
堆栈日志01可以看到 (附件中可以下载)
分析:大量HTTPHandler线程进行阻塞,造成无法处理客户端请求,造成假死现象
分析:与其同时,多个com.mchange.v2.async.ThreadPoolAsynchronousRunner 相关进程处于活跃状态,进行上锁的操作,这里是与c3p0连接池频繁创建连接,为应用中的代码中出现,中间件无c3p0连接池
所以此时中间件还在运行状态,但是不在对外处理处理,大量http请求处于阻塞状态,某些线程处于活跃状态,进行繁忙的操作
2、查看当前java进程jvm虚拟机垃圾回收状态是否异常:
查看进程gc情况 :jstat -gcutil pid 1000
参数:
- S0:幸存1区当前使用比例
- S1:幸存2区当前使用比例
- E:伊甸园区使用比例
- O:老年代使用比例
- M:元数据区使用比例
- CCS:压缩使用比例
- YGC:年轻代垃圾回收次数
- FGC:老年代垃圾回收次数
- FGCT:老年代垃圾回收消耗时间
- GCT:垃圾回收消耗总时间
分析:FGC 回收次数处于不断变化状态,并且远远高出YGC,正常的gc状态为 YGC 高于 FGC
.MinorGC:新生代区域对象的回收称为MinorGC,年轻代的回收频率特别的频繁,大多数对象都是在年轻代中创建并回收的。
FullGC/MajorGC:老年代区域对象的回收称为FullGC/MajorGC,老年代GC发生的频率会比新生代少,FullGC会占用大量的时间,导致程序一段时间无响应。
结论:
当前jvm虚拟机在频繁进行fullgc操作,导致程序一段时间无响应,可以推断出应用程序出现内存泄漏,需要抓取内存dump,分析heap.hprof 文件,
3、对内存信息进行分析:
下载案发现场的heap.hprof (容量比价大,大概5g左右),下载耗时
下载命令: jmap -dump:live,format=b,file=/usr/local/heap.hprof pid 生成dump文件了
使用工具对内存进行分析(mat工具或者jproflier)进行分析,
此处使用jproflier工具进行对heap.hpro 分析
建议:
StaticObj类有大量的ConcurrentHashMap和FileDownload类使用了比较多的String以及byte数组
应用可以优化一下相关代码 就是这两个类相关的操作