原创

如何定位并解决OOM问题

温馨提示:
本文最后更新于 2025年01月10日,已超过 12 天没有更新。若文章内的图片失效(无法正常加载),请留言反馈或直接联系我

当线上遇到OOM(Out Of Memory)问题时,该如何排查处理呢?

在此我们分为两种情况
1.在服务启动时添加OOM参数,防止OOM时项目崩溃而无法得到堆信息,建议配置

-XX:+HeapDumpOnOutOfMemoryError 内存溢出时自动生成dump文件
-XX:HeapDumpPath=heapdump.hprof 指定dump生成路径和文件名

2.在收到OOM告警而服务未崩溃时,导出内存快照
1.首先使用jpsps -ef|grep java等命令查看对应服务的pid
2.导出堆快照jmap -dump:format=b,file=*.hprof pid

将dump文件拷贝到本地,使用VisualVM等工具查看具体问题
dump

可以当前环境各种信息,以及引起OOM问题的类占用情况,这里可以看到String数组占用了98%的内存,我们在String[]上右键点击在新窗口打开查看详情:
查看详情

想详情页面选择第一个实例信息,选择GC Root查看引用信息,并展开GC Root内容,右键选择查看线程使用情况
查看详情

点击去可以看到我们线程中具体引起OOM的类及具体行情况
线程使用

可以看到,引起OOM问题为EurekaServiceApplication类第30行,打开代码,定位到对应代码,查看具体问题:
代码

可以看到,由于第30死循环无限往list添加数据,导致了OOM,至此,我们完成了一次OOM问题定位

除了死循环,还有未及时释放的远程连接、开启过多线程、未正确释放ThreadLocal引用等等都有可能造成OOM问题

正文到此结束
本文目录