记一次jvm内存溢出问题

1.起因:

晚上同事接到运维通知,生产上CPU占用率过高,如下图

初步判断不是程序死循环等原因引起的,然后确定了此服务器上只有我们一个应用,应该是我们的应用引起的,商量一番后,先治标,重启服务,然后测试环境解决问题,治本。

2.解决过程:

总结:百度一下你就知道,真的能解决很多问题(当然能google一下更好)

①在办公室使用TeamViewer远程同事的电脑在测试环境下找问题,同事在现场登录云桌面连接测试环境,最初先看日志,发现测试环境下在一天前服务也down掉了,然后日志里面提示 java.lang.OutOfMemoryError:Java heap space(堆内存溢出)这个醒目的错误,然后接着分析应用执行日志看看有没有其他错误(无其他业务,只有1分钟1次的定时任务在执行),没有报错。

②然后看给jvm分配的堆栈是不是太小,网上建议分配大小为内存的1/4,测试环境内存8G,分配了2G,应该没问题,上面也排除了死循环的情况

③然后根据网上的信息,决定使用jdk自带的分析工具进行分析,然后发现jmap jstat jstack等命令均无法执行,提示command not found,后来发现可能是服务器自带的OpenJDK没有提供这些工具,然后上传jdk安装替换,问题解决。jconsole是一个图形界面的监控工具,比较直观,不过很可惜由于是登录的远程桌面,无法使用。

④然后top查看占用内存较高的java进程,pid为16784

查看占用CPU或者内存过高的进程

linux下执行top,AIX下执行topas,然后查看占用过高的进程号,然后执行top -Hp pid

⑤查看当前jvm中内存里对象的实例数和内存占用数,并将结果输出到txt文件中方便查看

jmap -histo 16784 > a.txt

查看16784进程中对象总共占用内存大小,单位为byte

jmap-histo:live 16784|awk ‘{if(NR>3)a+=$3}END{print a}’

发现:对象占用内存很高,尤其是这些

LinkedHashMap

Hashtable

String

java.security.Provider$Service

java.security.Provider$ServiceKey

⑥可以将思路大概定位到,定时任务每分钟一次执行的时候,都会有对象存储到内存空间,但是此处应该有一个疑问,GC没执行吗,如果执行了,为什么空间没有回收?

⑦然后查看GC执行情况

查看GC回收频率:jstat -gcutil pid 打印频率(毫秒) 总打印次数

jstat -gcutil 167841000 20

分析GC在执行,但是老生代内存空间不仅没有释放,反而一直在增加,且占用率一直90%以上。

查看pid为16784的进程堆内存占用情况

jmap-heap 16784

⑧期间还使用jstack命令追踪线程执行情况,怀疑过是否有线程池ThreadPool使用,然后线程一直没有杀掉

跟踪pid为16784的所有线程执行情况并输出到txt文件中方便查看

Jstack 16784 > jstack_16784.txt

⑨最后根据百度的结果,决定生成dump文件,然后拿到本地使用eclipse的MAT(Memory Analysis Tools)内存分析工具进行更进一步的分析,Eclipse安装MAT很简单,联网后Help==>EclipseMarketplace==>Search,搜索安装重启eclipse完成;

然后让jiazt在测试环境生成dump文件

执行jmap -dump:format=b,file=heap.bin 16784,生成堆栈文件,通过MAT进行分析,生成的文件名为heap.bin,文件一般比较大,本次生成的大小为1.6G,压缩后300M

⑩然后拿到后,File==>Open File打开heap.bin这个文件,我此时的jvm空间最大分配是1G,后调至2G,才得以正常打开,不然会报错,打开后一个醒目的提示如下


圈11.如获至宝,赶紧百度,发现,这问题出现的还真不少,大概就是:JceSecurity这个jdk自带的加密工具类里面有不少的static修饰的常量和方法,定时任务每分钟执行一次会和网联交互,交互会加密,会调用这个工具类,然后产品中封装的加密流程调用这个工具类的时候是直接new出来的,然后这些static修饰的对象,每次都会产生,GC又不会回收他们,导致内存占用一直在增加,最后解决方法参考https://www.jianshu.com/p/b67bb91530b5,大概就是把new的过程改成private static在类里面初始化出来,到此问题解决。

圈12.建议:百度jvm差错分析工具和jvm调优,对于开发人员,看看可能导致问题出现的情况,然后避免,对于项目经理,如果以后用java开发项目,要注重这方面的问题。

后续补充一些截图进来。

以上,共勉。

参考https://www.jianshu.com/p/b67bb91530b5侵删。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值