记一次OOM导致服务器假死的排查过程
背景及现象
2019-09-19 2019-09-20这两天小程序后台服务多次出现假死情况,服务没挂但是访问接口无响应。
问题发现
运维的监控脚本发现某服务器上的应用无法访问发送邮件给项目成员。
查看应用日志只发现了一条连接的错误信息如下:
内容过于单薄,并不能通过该条日志定位到问题。
使用jmap -heap [pid] 查看当前应用的堆内存使用情况如下:
重点关注Heap Usage,可见新生代和老年代的空间满了,这里可以确定问题是OutOfMemery(OOM)。
现在的问题转移到定位产生内存溢出的根源,这里要先获取heap dump信息。
获取Heap Dump
这里主要介绍两种:
1、使用Jmap命令导出
jmap -dump:live,format=b,file=heap.hprof <pid>
2、使用 JVM 参数获取 dump 文件
-
-XX:+HeapDumpOnOutOfMemoryError
这个参数非常有用,需要我们分析内存的场景一般都是出现了OOM的情况。 -
-XX:+HeapDumpBeforeFullGC
当 JVM 执行 FullGC 前执行 dump。 -
-XX:+HeapDumpAfterFullGC
当 JVM 执行 FullGC 后执行 dump。
以上参数设置以后堆转储将默认在JVM的“当前目录”中生成,可结合如下命令显示重定向 dump 文件存储路径。
-XX:HeapDumpPath=test.hprof
注意:JVM 生成 Heap Dump 的时候,虚拟机是暂停一切服务的。如果是线上系统执行 Heap Dump 时需要注意。
得到dump文件后,将文件下载到本地备用。
分析Heap Dump文件
堆内存文件分析工具有几种,如jdk自带的Viusal VM,MAT,Jhat等。本次使用MAT来分析dump文件。MAT的内容参考[Memmeory Analyzer Tool(MAT)简介]
MAT 安装
下载地址:https://www.eclipse.org/mat/downloads.php
选择合适版本下载以后,解压到指定目录,右键执行MemoryAnalyzer.exe即可
使用MAT分析
运行MAT,打开下载下来的dump文件(hprof类型)。如果发现文件加载缓慢或者有卡顿可以