一次非常典型的 JVM OOM 事故 (要注意 where 1 = 1 哦)

当面对 JVM OOM 时,你会紧张吗 ? 会不会手足无措 ?

这篇文章,分享前段时间帮一位同学梳理面对 JVM OOM 事故时的解题思路。

首先从对话中,我们可以看到内存溢出呈现两种情况:

  • 运行一段时间之后,CPU 飙高 ;
  • 服务假死,表现出来日志没有任何输出。

我的第一反应是:非常明显的 JVM 内存溢出表现 ,不过不知道是爆炸性的内存增长,还是缓慢的内存增长。

于是,我回复:可以每隔一段时间 观察 top -p Pid (进程号) 看看应用的内存占用情况。

类似的效果见下图:

接下来,我让他通过 jstat -gcutil pid 1000 看看 gc 的频率 。

从图中,新生代 E 区和老年代基本都满了 ,我基本可以确定是海量大对象产生导致 JVM OOM 了。

定时任务这四个字如电光火石般在我眼前闪过,基本八九不离十了。

接下来,他发了张那段时间的监控图:

哇,这张图太有画面感了,我都能感觉到 GC 线程在四处灭火,但依然无法释放内存的彷徨。

最后,我有点担心,是不是 JVM 内存分配小了才导致 OOM 了,同学的回复是 : 12 G 。

我觉得内存大小还可以 ,一般情况下通过 jmap -heap pid 来查看,示例图如下:

分析到这里,基本上我得到了如下的结论:

1、要查看代码中是否有一次性查询海量对象的操作 ;

2、或者有什么公共的对象一直在使用,而忘记了释放;

3、12 G 对一般的小应用来讲是绰绰有余的,而且他们的应用非高并发场景,是内网系统。

最后,我建议观察在日志停的那个时刻到底做了哪些事情,那才是真正的案发现场


那到底是什么原因导致 JVM OOM 呢 ? 和我预期的基本一模一样:

SQL 语句类似下图,查询条件没有拼接好,导致全表扫描。


我们总结下,解决 JVM 内存溢出问题的流程:

1、分析事故现场(CPU、内存、日志);

2、通过 top -p Pid (进程号)分析进程资源占用,判断是爆炸性的内存增长,还是缓慢的内存增长。

3、 jstat -gcutil pid 1000 看看 gc 的频率 ,可以分析是否有大对象产生以及 查看 GC 频率。

4、 jmap -heap pid 分析真实的 JVM 内存占用 ,确认是否真的内存分配得太小了。

5、 事故发生当时到底做了什么,有没有出现类似于内存或者 CPU 占用呈现脉冲飙高样子。

6、 若有飙高的场景,分析彼时彼刻到底有哪些操作。

7、 若是缓慢增长,则考虑使用 MAT 结合排除法分析内存占用。

上面的流程是我解决过内存溢出的套路,虽然很糙,但很实用,比如曾经帮助艺龙支付团队解决过订单查询内存溢出问题、西南某航空公司用户中心内存溢出问题等等。

最后,我想说:一定要注意 where 1 = 1 哦 ,真的出现太多次啦。

相关推荐
千叶寻-1 小时前
正则表达式
前端·javascript·后端·架构·正则表达式·node.js
小咕聊编程2 小时前
【含文档+源码】基于SpringBoot的过滤协同算法之网上服装商城设计与实现
java·spring boot·后端
追逐时光者8 小时前
推荐 12 款开源美观、简单易用的 WPF UI 控件库,让 WPF 应用界面焕然一新!
后端·.net
Jagger_8 小时前
敏捷开发流程-精简版
前端·后端
苏打水com9 小时前
数据库进阶实战:从性能优化到分布式架构的核心突破
数据库·后端
间彧10 小时前
Spring Cloud Gateway与Kong或Nginx等API网关相比有哪些优劣势?
后端
间彧10 小时前
如何基于Spring Cloud Gateway实现灰度发布的具体配置示例?
后端
间彧10 小时前
在实际项目中如何设计一个高可用的Spring Cloud Gateway集群?
后端
间彧10 小时前
如何为Spring Cloud Gateway配置具体的负载均衡策略?
后端
间彧10 小时前
Spring Cloud Gateway详解与应用实战
后端