OOM排查

可能原因:

(1)内存确实分配过小,内存确实不够用;

(2)某一个对象被频繁申请,却没有释放,内存不断泄漏,导致内存耗尽;

(3)某一个资源被频繁申请,系统资源耗尽,例如:不断创建线程,不断发起网络连接;

排查方法:

一、确认是不是内存本身就分配过小方法:jmap -heap + PID

二、找到最耗内存的对象方法:jmap -histo:live PID | more

会打印(1)实例数;(2)所占内存大小;(3)类名;

三、确认是否是资源耗尽工具:(1)pstree(2)netstat

OOM排查  详细帖子

具体操作:

1、先查看应用进程号pid: ps  -ef | grep  应用名(或者jps命令也可以看到PID)

2、查看pid垃圾回收情况:  jstat  -gc  pid  5000(时间间隔)

3、开启OOM快照:

-XX:+HeapDumpOnOutOfMemoryError(开启堆快照)

-XX:HeapDumpPath=C:/m.hprof(保存文件到哪个目录)

4、dump 查看方法栈信息:

jstack -l  pid  >  /home/test/jstack.txt

5、dump 查看JVM内存分配以及使用情况

jmap  -heap  pid  >  /home/test/jmapHeap.txt

6、dump jvm二进制的内存详细使用情况 (效果同在Tomcat的catalina.sh中添加 set JAVA_OPTS=%JAVA_OPTS% -server -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/home/test//oom.hprof  此文件需要借用内存分析工具如:Memory Analyzer (MAT)来分析)

jmap -dump:format=b,file=/home/test/oom.hprof  pid

OOM一般有以下两种情况:

1、年老代堆空间被占满

异常:java.lang.OutOfMemoryError:java  heap space

说明:这是最典型的内存泄漏方式,简单说就是所有堆空间都被无法回收的垃圾对象占满,虚拟机再也无法分配新空间

解决方案:这种方式解决起来比较简单,一般就是根据垃圾回收前后的情况对比,同时根据对象引用情况(常见的集合对象引用)分析,基本都可以找到泄漏点。

2、持久代被占满

异常:java.lang.OutOfMemoryError:PermGen space

说明:Perm 空间被占满,无法为新的 class 分配存储空间而引发的异常。这个异常以前是没有的,但是在 java 大量使用反射的今天这个异常就比较常见了。主要原因是大量动态反射生成的类不断被加载,最终导致 Perm 区被占满。更可怕的是,不同的 classLoader 即便使用相同的类,但是都会对其进行加载,相当于同一个东西,如果有 N 个classLoader 那么它将会被加载 N 次。因此,在某些情况下,这个问题基本视为无解,当然,存在大量 classLoader 和大量反射类的情况并不多

解决方案:增加持久代内存 ,例如:-XX:MaxPermSize=16M

另附:

JVM常用调优命令详解

你可能感兴趣的:(OOM排查)