-
问题背景
今天接到反馈生产环境一批量功能报错,查看生产环境发现报了OOM,遂进行排查定位 -
排查过程
-
首先,第一反应查看服务启动jvm参数,
发现该服务设置了最大堆内存为1024m即1G,当时设置这个的初衷可能是想对这个核心服务设置较大的内 存,但是设置1024m真的比默认的会大吗?
了解到部署该服务的服务器是8和32G配置,网上查阅资料,得知-Xmx默认值可以达到物理内存的1/4(存 疑,未找到官方说法,不过可以确定会远远大于当前配置的1G)-
紧急解决方案
通过以上分析可知,由于我们之前没搞清楚-Xmx默认大小以及机器物理内存大小,设置的-Xmx=1024m反而设置小了。因为生产环境时间紧迫,先去到-Xmx -Xms两个参数,重启服务,持续观察,再未出现OOM的情况。
-
OOM排查
以上紧急处理方法只是治标不治本,为防止该问题以后再发生,需要搞清楚为什么会包OOM。- 日志分析
通过错误日志定位到具体代码位置,以及疑似与字符串拼接有关,下图是问题代码:
找到问题代码,发现是对一个集合进行fastjson的转json字符串操作,初步定位是fastjson的转json字符串出现的问题。
-
内存快照分析
首先需要在启动脚本中指定参数:-XX:+HeapDumpOnOutOfMemoryError,让发生OOM后将内存快照保留下来(具体快照文件需要生成在哪个目录命令可自行百度)
内存快照长下面这个样子:
内存快照分析工具,目前使用过两个:1.MemoryAnalyzer (可自行百度下载)2.jvisualvm(这个是jdk自带的,已jdk1.8为例,是 %java_home%/bin/jvisualvm.exe 这个,双击打开就行):
用jvisualvm分析:
发现char[]占的内存最大,达到76%,双击看其示例中内容:
发现这个示例中的内容就是报错代码 JSON.toJSONString(visitorsCountDos) visitorsCountDos集合中每个元素的参数,由此可以分析出,这些char[]大多数是JSON.toJSONString(visitorsCountDos)执行时fastjson拼接集合中对象的属性,因为这个集合数据太大了,导致fastjson序列化拼接时占用内存太多,而内存溢出。
-
结论
- 数据太大(尤其集合)不要使用fastjson的JSON.toJSONString()可能会造成内存溢出
- jvm参数配置前一定要搞清楚每个参数的含义再配置,否则可能南辕北辙
-
记一次OOM的排查定位处理(OutOfMemoryError排查)
最新推荐文章于 2024-07-07 17:57:43 发布