文档章节

一次线上OOM故障排查经过

黄亿华
 黄亿华
发布于 2014/03/05 10:02
字数 752
阅读 4689
收藏 138
JVM

本文是一次线上OOM故障排查的经过,内容比较基础但是真实,主要是记录一下,没有OOM排查经验的同学也可以参考。

现象

我们之前有一个计算作业。最近经常出现不稳定,无法正常响应的情况。具体表现是:各种连接超时,从mysql、mongodb和zookeeper到netty,能超时的都超时过了。其他看不到太多有效的异常。

所以我们首先怀疑的是网络问题,打电话跟运维确认,运维说网络问题的可能性几乎为0,因为我们的机器是虚机,宿主机上的其他设备都运转正常。程序问题的可能性更大。继续从应用日志和tomcat的catalina.out中查找日志,发现有一些OutOfMemoryError异常。实际上,出现这个异常就代表内存不够了。

我们使用cat(公司的Java监控平台,已开源https://github.com/dianping/cat)查看堆使用的情况,看到如下的东西:

cat oom

Memory Free已经接近了0,同时产生了大量的fullgc。

回到之前的连接timeout,我们知道,Java的连接timeout,除了网络传输的时间,也包括了Java程序处理的时间,所以OOM导致timeout也不奇怪了。

工具和排查

之前JVM分析做的很少,在同事的帮助下,结合一点资料,完成了基本的分析。

首先可用的是

jmap -histo PID

这个命令会将内存中最终保存的对象列出来。

jmap-histo

其中"["表示数组,例如"[B"是byte[],具体可以看Class.getName()的Javadoc。

但是这个只能粗略定位原因,如果要仔细分析,需要知道是哪些个对象持有了它,这个时候,就需要dump内存下来,再离线分析了。

dump内存的命令是:

jmap -dump:format=b,file=/home/admin/dump.bin PID

此操作异常耗时,我跟运维在假死的机器上尝试了几次,竟然把tomcat进程干掉了,使用时还是小心为妙…跟同事讨论,认为jmap -dump实际上也是往运行的JVM实例发送一个dump请求,所以如果实例内存不足,dump很可能会失败。比较好的做法是先降低一部分负载(比如把线上的机器先切下线)再试。

我这里使用VisualVM进行分析,大致效果如下:

visual-vm

这里选择“计算保留大小”。这个保留大小是递归计算实例之间的依赖,得到的总大小。因为去掉了循环依赖,所以并不完全准确,但是用于排查够了。选择保留大小最大的实例,一般就是罪魁祸首了!

visual-vm2

最后排查出的结果,是公司的RPC中间件使用了ThreadLocal来保存一个context,但是最后却没有释放。按照架构组的说明,升级了版本,问题解决!

© 著作权归作者所有

共有 人打赏支持
黄亿华

黄亿华

粉丝 2324
博文 131
码字总数 116344
作品 7
程序员
私信 提问
加载中

评论(30)

cheeeeeeeeeeen
cheeeeeeeeeeen
Threadlocal不是会自动释放吗?
黄亿华
黄亿华

引用来自“唯一only”的评论

博主,从计算保留大小开始有点看不懂,能不能讲仔细点。谢谢

计算保留大小是VisualVM的一个功能,这么说很难说清楚,建议操作一下就理解了
唯一only
唯一only
博主,从计算保留大小开始有点看不懂,能不能讲仔细点。谢谢
james_you
james_you

引用来自“黄亿华”的评论

引用来自“sharkbobo”的评论

你截出来的图,并不能说明你说的问题,可能你没有用真实的图,其实发这种图,没有什么商业机密啊

其实本文主要是说明一下方法,故障原因有很多种类,列举出来也没啥意义。

呵呵,好吧。其实排查oom也就是这样
黄亿华
黄亿华

引用来自“sharkbobo”的评论

你截出来的图,并不能说明你说的问题,可能你没有用真实的图,其实发这种图,没有什么商业机密啊

其实本文主要是说明一下方法,故障原因有很多种类,列举出来也没啥意义。
james_you
james_you
你截出来的图,并不能说明你说的问题,可能你没有用真实的图,其实发这种图,没有什么商业机密啊
james_you
james_you
你截出来的图,并不能说明你说的问题,可能你没有用真实的图,其实发这种图,没有什么商业机密啊
james_you
james_you
你截出来的图,并不能说明你说的问题,可能你没有用真实的图,其实发这种图,没有什么商业机密啊
品不懂
品不懂
mark 学习了
wxpier
wxpier

引用来自“黄亿华”的评论

引用来自“wxpier”的评论

实际试了一下,发现一个问题,第一个jvvm图中没有【保留】这一列,第二个jvvm图中出现了这一列,我用jdk1.7中的jvvm测试,发现并没有这一列,选择隐藏和显示列按钮,也没有,请问,需要安装插件吗?

我是点击到“实例”tab,出现“计算保留数”之后,切换回来出现的这一列。

不知道你用的哪个VVM,其实呢,jvvm中没有这一列,只有在vvm中才有,直接在隐藏和显示列按钮中选择就可以了
Node 案发现场揭秘 —— Coredump 还原线上异常

Node 案发现场揭秘 —— Coredump 还原线上异常 const article = { title: "Node.js", content: "Hello, Node.js" }; setTimeout(() => {console.log(article.b.c);}, 1000); $ npm install ......

黄一君
08/03
0
0
netty 堆外内存泄露排查思路

这篇文章对于排查使用了 netty 引发的堆外内存泄露问题,有一定的通用性,希望对你有所启发 背景 最近在做一个基于 websocket 的长连中间件,服务端使用实现了 socket.io 协议(基于websock...

匠心零度
09/19
0
0
netty 堆外内存泄露排查盛宴

点击上方“闪电侠的博客”,关注公众号 纯技术干货文章第一时间送达! 这篇文章对于排查使用了 netty 引发的堆外内存泄露问题,有一定的通用性,希望对你有所启发 背景 最近在做一个基于 we...

闪电侠的博客
09/04
0
0
CPU100%问题快速定位思路

在我日常运维工作中,无论自己 或同事、朋友总会问我,服务器CPU使用率100%,卡死了,这样的话,那今天咱们就一起模拟故障,进行细致的分析,首先介绍下,CPU出现问题的几种原因: 一、CPU 1...

邱月涛
06/04
0
0
反思一次Exchange服务器运维故障

本文是对2018年8月9日公司Exchange邮件系统邮件流故障的故障发现、故障处理和故障修复的过程记录和总结反思。帮助自己总结经验和吸取教训,同时也作为一次反面教材让其他运维或管理员吸取教训...

urey_pp
08/10
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Mariadb二进制包安装,Apache安装

安装mariadb 下载二进制包并解压 [root@test-a src]# wget https://downloads.mariadb.com/MariaDB/mariadb-10.2.6/bintar-linux-glibc_214-x86_64/mariadb-10.2.6-linux-glibc_214-x86_64.t......

野雪球
今天
3
0
ConcurrentHashMap 高并发性的实现机制

ConcurrentHashMap 的结构分析 为了更好的理解 ConcurrentHashMap 高并发的具体实现,让我们先探索它的结构模型。 ConcurrentHashMap 类中包含两个静态内部类 HashEntry 和 Segment。HashEnt...

TonyStarkSir
今天
3
0
大数据教程(7.4)HDFS的java客户端API(流处理方式)

博主上一篇博客分享了namenode和datanode的工作原理,本章节将继前面的HDFS的java客户端简单API后深度讲述HDFS流处理API。 场景:博主前面的文章介绍过HDFS上存的大文件会成不同的块存储在不...

em_aaron
昨天
3
0
聊聊storm的window trigger

序 本文主要研究一下storm的window trigger WindowTridentProcessor.prepare storm-core-1.2.2-sources.jar!/org/apache/storm/trident/windowing/WindowTridentProcessor.java public v......

go4it
昨天
7
0
CentOS 生产环境配置

初始配置 对于一般配置来说,不需要安装 epel-release 仓库,本文主要在于希望跟随 RHEL 的配置流程,紧跟红帽公司对于服务器的配置说明。 # yum update 安装 centos-release-scl # yum ins...

clin003
昨天
11
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部