一次线上OOM 的定位

一次线上OOM 的定位

问题背景

收到业务监控报警

[告警名称:jvm.fullgc.count]
[告警指标:jvm.fullgc.count]
最近5个点值:[N/A,N/A,N/A,N/A,1606]
触发规则:
[最新5个点求和 > 5 ]

数据时间:2021-03-31 07:53:00
告警时间:2021-03-31 07:54:21

持续时长:just now

查看监控数据

fullgc.count (分钟级别)
fullgc.count (分钟级别)

登录机器发现,服务已挂掉。

问题定位

查看 JVM 参数配置,并没有配置 HeapDumpOnOutOfMemoryError 参数。查看异常日志,发现报错信息如下

OOM
OOM

可见,是元空间内存溢出。查看 JVM 关于元空间的参数配置

-XX:MetaspaceSize=250m -XX:MaxMetaspaceSize=250m

一般而言,我们调整上述参数,增加元空间的大小即可。但仍存在一个疑问,服务已经运行了很久了,为什么之前没有问题,而现在突然出现问题?

  1. 查看服务的发布记录,发现 3.30 号有一位小同学对此服务进行了发布。咨询了一下发布的功能和逻辑、查看其代码及涉及的数据量后,发现其新功能每隔几分钟就会获取大量的数据并处理,此时会占用大量的内存。在处理的过程中,会动态产生类。

  2. 观察元空间的占用统计情况,发现即使在没有执行新功能的时候,元空间的占用也达到了 90% 以上。

解决方案

主要通过以下三个手段:

  1. 增加元空间的大小至 350M
  2. 将单次执行任务的数据量减少。主要手段为分页获取数据,虽然对元空间的影响不大,但可以减少单次对新生代的内存占用
  3. 增加对元空间占用大小的监控,当元空间占用大小超过 80% 时,发送提醒通知,当达到 90% 时,发送报警通知
posted @ 2021-04-04 23:38  feshfans  阅读(130)  评论(0编辑  收藏  举报