jvm oom事故你会慌吗?
遇到一个问题,突然间CPU飙升了,这种情况大概率是不是内存泄漏了吧,重启服务之后运行一段时间,又是这样的。
jvm呈现两种情况,
1.运行一段时间后,CPU飙升
2.服务假死,表现出来日志没有任何输出。
非常明显的jvm内存溢出表现,不过不知道是不是爆炸性的内存增长,还是缓慢的内存增长,可以每隔一段时间观察一下top-P- Pid(进程号)看看应用的内存占比情况。
3.在接下来,看看jstat -gcutil pid 1000 看看GC的情况
新生代E区和老年代基本都满了,我基本可以确定是海量大对象产生导致了JVM OOM,查询数据库操作吧。
4.看看是不是内存太小了导致了 OOM了,同学回复:12G内存大小还可以,一般情况下通过jmp-heap pid
分析到这里基本可以得到如下的结论
1.要查看代码中是否有一次性查询海量对象的操作?
2.或者有没有没有什么公共的对象在使用,而忘记了释放
3.12G对一般的小应用来讲戳戳有余 的,而且他们的应用非高并发场景,是内网系统。
最终原因是:写sql的时候直接全表查询,把几千万的数据放在List里面。
sql语句类似下图,查询提交没有拼接好,导致全表扫描。
解决JVM OOM内存溢出问题的流程
1.分析事故现场(CPU,内存,日志);
2.通过top -p Pid (进程号)分析进程资源占用,判断是爆炸性的内存增长,还是缓慢的内存增长
3.jstat -gcutil pid 1000 看看gc的频率,可以分析是否有大对象产生以及查看一下GC频率
4.jmap -heap pid 分析真实的jvm内存占用确认是否真的内存分配太小了。
5.故事发生当时做到什么?有没有出现类似于内存或者CPU占用呈现脉冲飙高的样子
6.若是飙高了,分析此时此刻到底哪些场景
7.若是缓慢增长,则考虑使用MAT,结合排除法分析内存占用。
在内存问题上:大家一定要注意自己的sql where 1=1哦,真的出现太多次了。