内容简介:某Java服务(假设PID=10765)出现了OOM,如何快速定位?Java服务出现OOM,最常见的原因是:更具体的,可以按照以下步骤,使用以下工具排查。
某 Java 服务(假设PID=10765)出现了OOM,如何快速定位?
Java服务出现OOM,最常见的原因是:
- 内存确实分配过小,内存确实不够用;
- 某一个对象被频繁申请,却没有释放,内存不断泄漏,导致内存耗尽;
- 某一个资源被频繁申请,系统资源耗尽,例如:不断创建线程,不断发起网络连接;
更具体的,可以按照以下步骤,使用以下 工具 排查。
一、确认是不是内存本身就分配过小
方法:jmap -heap 10765
如上图,可以查看新生代,老生代堆内存的分配大小以及使用情况,看是否本身分配过小。
二、找到最耗内存的对象
方法:jmap -histo:live 10765 | more
如上图,输入命令后,会以表格的形式显示存活对象的信息,并按照所占内存大小排序:
- 实例数;
- 所占内存大小;
- 类名;
是不是很直观?对于实例数较多,占用内存大小较多的实例/类,相关的代码就要针对性review了。
画外音:需要说明的是,jmap -histo:live会执行一次FGC,如果仍无法定位,可dump内存,通过Java内存分析工具MAT(Memory Analyzer Tool)线下进行分析。
上图中占内存最多的对象是RingBufferLogEvent,共占用内存18M,属于正常使用范围。
如果发现某类对象占用内存很大(例如几个G),很可能是类对象创建太多,且一直未释放。例如:
- 申请完资源后,未调用close()或dispose()释放资源;
- 消费者消费速度慢(或停止消费了),而生产者不断往队列中投递任务,导致队列中任务累积过多;
三、确认是否是资源耗尽
工具:
- pstree
- netstat
查看进程创建的线程数,以及网络连接数,如果资源耗尽,也可能出现OOM。 这里介绍另一种方法,通过
/proc/${PID}/fd /proc/${PID}/task
可以分别查看句柄详情和线程数。
例如,某一台线上服务器的sshd进程PID是9339,执行:
如上图,sshd共占用了四个句柄:
- 0 -> 标准输入;
- 1 -> 标准输出;
- 2 -> 标准错误输出;
- 3 -> socket(容易想到是监听端口);
sshd只有一个主线程PID为9339,并没有多线程。
所以,只要
ll /proc/${PID}/fd | wc -l ll /proc/${PID}/task | wc -l (效果等同pstree -p | wc -l)
就能知道进程打开的句柄数和线程数。
【本文为51CTO专栏作者“58沈剑”原创稿件,转载请联系原作者】
以上所述就是小编给大家介绍的《Java服务,内存OOM了,如何快速定位?》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 定位golang内存泄露
- 用 recon 定位 Erlang 内存泄露问题
- Android内存泄漏定位、分析、解决全方案
- 深入理解Java虚拟机之对象的内存布局、访问定位
- 认识绝对定位,相对定位
- 移动端页面头部固定定位的绝对定位实现
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Introduction to Computation and Programming Using Python
John V. Guttag / The MIT Press / 2013-7 / USD 25.00
This book introduces students with little or no prior programming experience to the art of computational problem solving using Python and various Python libraries, including PyLab. It provides student......一起来看看 《Introduction to Computation and Programming Using Python》 这本书的介绍吧!