JAVA的OOM案例
文章目录
金三银四跳槽季最常见的JAVA面试题跑不掉的一个基本就是有没有碰到OOM的情况,以及排查OOM的过程。
正好赶上生产环境某个微服务出现OOM,将排查过程列一下,给找工作的朋友们贡献一个案例
缘起
某个不太重要的系统忽然报警,系统CPU load较高持续了一段时间,正常情况下这台服务器偶尔也会load偏高,但很快会降下来。
过程
首先找运维上服务器TOP看了一下CPU偏高的进程,发现是一个不常用的微服务,检查了git log发现最近一次、多次上线只是一些简单的增删改查,不存在内存泄漏的上线代码。
然后在服务器执行jstat -gccause 进程ID 5s
,发现full GC频繁(10s左右一次),基本不用看jstack之类就知道应该是OOM造成的(实际系统日志中也能看到OutOfMemoryError的异常,但因为不太重要的微服,所以未加报警)
因为所有微服务的启动命令中统一有增加-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=$1_dump.hprof
,会在发生OOM时候自动转存内存镜像
从服务器拉了dump文件导入JProfiler后,根据下图步骤:
- 点击
Biggest Objects
- 在占用最大的对象上右键选择
Use Selected Objects
- 在弹出的提示框中选择
Use Selected Objects
,注意Referens
的下拉列表中选择Incoming references
- 展开就可以看到结果
溯源
根据内存泄漏的调用方法,分析代码后发现是一个小伙伴去年9月份的一段代码,导出数据时候用了一个while(true)的分页循环数据的逻辑,但最后没有page++
为啥半年多没出问题的原因就在于之前那部分数据没超过一页……
文章作者 pengxiaochao
上次更新 2022-04-02
许可协议 不允许任何形式转载。