一次线上OOM故障排查经过

简介: 转贴:http://my.oschina.net/flashsword/blog/205266   本文是一次线上OOM故障排查的经过,内容比较基础但是真实,主要是记录一下,没有OOM排查经验的同学也可以参考。

转贴:http://my.oschina.net/flashsword/blog/205266

 

本文是一次线上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分析做的很少,在同事的帮助下,结合一点资料,完成了基本的分析。

首先可用的是

1 jmap -histo PID

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

jmap-histo

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

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

dump内存的命令是:

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

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

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

visual-vm

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

visual-vm2

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

目录
相关文章
|
Arthas 监控 Java
Arthas 实践——生产环境排查 CPU 飚高问题
13:40 收到我们的生产环境服务器绿版 CUP 超负载告警通知。此时心里只有一个想法,重启大法好,马上登录服务器,执行 top 发现进程 30247 和 28337 占用 CPU 为 200 多和100 多基本占用了 4 核的 3 核,整个过程大概用时 30 秒,维护群依然很平静,运营的电话也没打过来,这时候我断定,这次问题应该影响面很小,用户可能也暂时没有发现,好吧,还有时间做排查。
Arthas 实践——生产环境排查 CPU 飚高问题
|
3月前
|
存储 监控 Java
线上OOM排查
本文介绍了JDK工具的使用方法及其应用场景。首先详细说明了`jps`、`jstack`、`jstat`和`jmap`等工具的基本用法及参数含义,帮助开发者实时监控Java进程的状态,诊断线程问题及内存使用情况。接着介绍了`jvisualvm.exe`和`MemoryAnalyzer.exe`两款内存诊断工具,展示了如何通过这些工具进行内存分析。最后,文章提供了在线上OOM故障排查的具体步骤,并给出了解决方案示例,以便开发者更好地理解和解决实际问题。
线上OOM排查
|
5月前
|
运维 监控 Java
(十)JVM成神路之线上故障排查、性能监控工具分析及各线上问题排错实战
经过前述九章的JVM知识学习后,咱们对于JVM的整体知识体系已经有了全面的认知。但前面的章节中,更多的是停留在理论上进行阐述,而本章节中则更多的会分析JVM的实战操作。
129 1
|
5月前
|
缓存 Java Linux
开发与运维内存问题之线上遇到故障,使用jstat命令发现Old区持续增长如何解决
开发与运维内存问题之线上遇到故障,使用jstat命令发现Old区持续增长如何解决
50 2
|
7月前
|
SQL 运维 NoSQL
【Redis 故障排查】「连接失败问题排查和解决」带你总体分析CPU及内存的使用率高问题排查指南及方案
【Redis 故障排查】「连接失败问题排查和解决」带你总体分析CPU及内存的使用率高问题排查指南及方案
220 0
|
监控 NoSQL Java
【线上问题】服务CPU彪高排查
后端程序员出去面试经常会有面试官喜欢问你有没有排查过线上问题,遇到后怎么排查的。
545 0
【线上问题】服务CPU彪高排查
|
监控 Java
【线上问题排查】CPU100%和内存100%排查
【线上问题排查】CPU100%和内存100%排查
186 1
|
Java
面试拆解:系统上线后Cpu使用率飙升如何排查?
面试拆解:系统上线后Cpu使用率飙升如何排查?
145 0
|
存储 SQL Java
线上又 OOM 了 ,教你快速定位问题~
线上又 OOM 了 ,教你快速定位问题~
线上又 OOM 了 ,教你快速定位问题~
|
存储 监控 安全
JVM内存管理机制&线上问题排查
本文主要基于“深入java虚拟机”这本书总结JVM的内存管理机制,并总结了常见的线上问题分析思路。文章最后面是我对线上故障思考的ppt总结。 Java内存区域 虚拟机运行时数据区如下图所示: 15291199000153.jpg 方法区:方法区又称为永生代(Permanent Generation)是线程共享的内存区域。
3012 0