快乐赚

oom是什么意思(内存溢出/内存泄漏分析过程)

 人阅读 | 作者舞动奇迹 | 时间:2024-01-31 13:26

一、名词解释

  • 内存泄漏(memory leak)含义:是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄漏似乎不会有大的影响,但内存泄漏堆积后的后果就是内存溢出。
  • 内存溢出(out of memory):简称OOM含义:程序申请内存时,没有足够的内存分配给使用者

注:内存泄漏的堆积最终会导致内存溢出

二、OOM常见报错信息

常见报错有下面2类:

  • java.lang.OutOfMemoryError: Java heap spacejava堆空间不足,一般是堆内存设置过小 或 堆空间的对象太多,不能被GC清除
  • java.lang.OutOfMemoryError: GC overhead limit exceeded如果Java进程花费98%以上的时间执行GC,并且每次只有不到2%的堆被恢复,则JVM抛出此错误。想象一下,如果不抛异常,再进行下去的话,系统就只能一直GC中,还有能力为你的服务吗?

三、模拟OOM

为了便于复现,我们先设置jvm参数:

-Xms5m -Xmx5m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=E:\JAVA\dump

-Xms5m :堆初始内存(5m便于复现OOM)
-Xmx5m :堆最大内存(5m便于复现OOM)
-XX:+HeapDumpOnOutOfMemoryError:当JVM发生OOM时,自动生成DUMP文件(.hprof)
-XX:HeapDumpPath=E:\JAVA\dump :发生oom时,生成.hprof文件存放地址

编写程序,制造大量对象放入集合中:

    private static class MyOOM 

    public static void main(String[] args) 
    }

运行结果如下:

java.lang.OutOfMemoryError: Java heap space
Dumping heap to E:\JAVA\dump\java_pid2892.hprof ...
Heap dump file created [9507297 bytes in 0.068 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3210)
    at java.util.Arrays.copyOf(Arrays.java:3181)
    at java.util.ArrayList.grow(ArrayList.java:261)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
    at java.util.ArrayList.add(ArrayList.java:458)
    at com.abao.demo.Demo.main(Demo.java:22)

四、分析与改进措施

一般解决OOM有如下几种方法:

1、增大堆空间

既然堆内存少了,那就增加堆内存即可。但是再大的内存也会有用尽的时候,因此此方法治标不治本。

2、找到占用内存大的地方,优化代码

怎么定位呢?通过jvm生成的dump文件定位。

运行结果中已经表明,当发生OOM时,堆栈信息的文件的存放路径了。这里我们使用工具打开java_pid2892.hprof。常用工具有 jvisualvm(jdk自带)、MAT、arthas(阿里的工具)等。

我们选择jvisualvm(cmd窗口中输入 jvisualvm就会自己打开该工具)

 

在概要-堆转储上的线程 中查看发生OOM的地方,点击进入看详情(此处可以看到发生OOM在哪一行代码

 

结合上下2张图可以看出来,当向ArrayList中插入第240098个MyOOM对象时出现内存溢出了。

 

因此我们可以看看整个jvm中对象信息,可以看到此对象产生的数量太多了,占用堆空间最大。

 

3、怎么改

既然找到哪一行代码发生的问题,以及是哪一个对象了。便可以适当清除集合,比如下方代码:

    public static void main(String[] args) 
        }
    }

综上,只要我们设置合理的堆栈大小,再配合一定的代码优化便可一定程度上解决OOM,让程序更健壮。


文章标签:

本文链接:『转载请注明出处』