OutOfMemoryError问题排查
- 近期生产环境每隔一段时间就会出现cup过高,导致服务不能访问
- 再cup报警的时候通过
top
命令查看占用cup较高的应用 - 找到对应应用的进程编号,dump对应内存文件
jmap -dump:live,format=b,file=/mnt/app/heapdump.phorf pid
- 通过
jmap
命令dump内存文件的失败了 - 查看对应应用的异常信息

- 然后看一下系统对应fc的情况
jstat -gcutil pid 1s

- 可以看到是一直在fgc,切并未清理出对应的空间
- 为了不影响生产环境系统的使用,就加大JVM内存,对服务的重启
- 把JVM内存调到了4G,并加上了内存溢出自动dump内存文件
export CATALINA_OPTS="$CATALINA_OPTS -server -Xms4g -Xmx4g -Xss256k -XX:+UseParallelOldGC -XX:+UseCMSCompactAtFullCollection -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/../logs/oom.hprof"
- 重启服务之后看下gc的情况,gc正常
- 在服务运行几天之后cup又报警了,自动dump了内存文件,看了下自动dump文件成功,手动改了下dump文件的名称(多节点配置,为了区分哪台服务器上的文件)
- 看了下dump文件大小9.1G,把JVM内存调整到10G (dump文件是实际存活对象或未及时回收的对象所占的空间),重启服务之后对dump文件进行分析

- 把dump文件压缩之后,下载到本地
使用jdk自带java VisualVM
对dump文件进行分析 - 加载dump文件之前,先设置下
java VisualVM
内存,在jdk下的lib目录下

visualvm\etc
下的visualvm.conf
文件的visualvm default options
配置

- 设置完内存时候打开
java VisualVM
,WIN+R 输入jvisualvm
命令即可

- 点击文件,装入,选择下载到本地的dump文件

- 选择dump文件,点击打开即可

- 由于文件比较大,加载需要一段时间
- 加载完之后之后可以看到异常信息

- 点击异常信息,可以直接跳转到异常信息详情

- 这里可以看到,我们自己的类,找到对应的代码定位问题处理即可
- 这里我们看下内存对象的情况,点击【类】选项卡

- 点击对象,右键在【实例实图中显示】


- 其实在【类】的页面可以看到
org.apache.xmlbeans
包下的类占比很大,全部加起来80%左右了,这个是poi相关的类,是操作excel不当导致的

- 然后排查代码,发现操作excel存在流关闭不当的情况
- 调整代码之后,重新发布应用,查询cup情况

- 然后dump下内存文件,分析新的内存文件,并未发现过多poi对象

- 完善文件流关闭
- 控制导出数据量,做分批次导出
- JVM内存大小调整到2G,然后持续观察服务情况
- 查看gc情况

- 查看内存使用情况
jmap -heap pid

- 暂时未发现内存溢出的情况,后续在持续观察服务情况