目录
首先,说说什么是OOM?
OOM 全称 “Out Of Memory”,表示内存耗尽。
官方说明:Thrown when the Java Virtual Machine cannot allocate an object because it is out of memory, and no more memory could be made available by the garbage collector.
当 JVM 因为没有足够的内存来为对象分配空间,并且垃圾回收器也已经没有空间可供回收时,就会抛出这个错误。(注:非exception,已经严重到不足以被应用处理)。
为什么会出现 OOM,一般由这些问题引起
-
分配过少:JVM 初始化内存小,业务使用了大量内存;或者不同 JVM 区域分配内存不合理
-
内存泄漏:某一个对象被频繁申请,不用了之后却没有被释放,发生内存泄漏,导致内存耗尽
内存泄漏:申请使用完的内存没有释放,导致虚拟机不能再次使用该内存,此时这段内存就泄露了。因为申请者不用了,而又不能被虚拟机分配给别人用
内存溢出:申请的内存超出了 JVM 能提供的内存大小,此时称之为溢出
内存泄漏持续存在,最后一定会溢出,两者是因果关系
Java OOM的三大核心场景
场景一、堆内存OOM
OOM的场景和解决方案
分析方法通常有两种:
-
类型一:在线分析,这个属于轻量级的分析:
-
类型二:离线分析,这个属于重量级的分析:
类型一:在线OOM分析,这个属于轻量级的分析:
在线OOM分析,包括两种方法:
在线分析方法一:使用 jmap 分析TOP N对象
jmap(Java Memory Map)是jdk自带的java内存映像工具,使用jmap能够系统运行时的内存信息,同时能够将内存dump下来,分析内存泄露的问题。
-
第一步:jmap 查看进程中占用资源最大的前N个对象,
-
第二步:知道哪个对象消耗内存了,再去定位代码就不难了。然后 导出 快照文件 jmap -dump:live,format=b,file=文件路径/文件名 pid
这里我们使用它 -dump 选项,将内存信息dump到服务器某个地方,然后传到本地使用内存分析工具MAT进行内存分析。
jmap -dump:live,format=b,file=文件路径/文件名 pid
live:就是只dump 活着的对象 format=b 使用二进制 file= 快照文件保存路径
在线分析方法二:使用 Arthas 在线分析OOM
使用 Arthas 火焰图,分析TOP N对象 和调用堆栈
请参见视频, 和尼恩的《Arthas 学习圣经 v2》 最新版本