何时会触发OOM

1. java.lang.OutOfMemoryError:Java heap space

申请堆内存不足

  • 堆内存不足
  • 内存泄漏

2. java.lang.OutOfMemoryError:GC overhead limit exceeded

GC发现GC效率不高

  • 默认情况下,当应用程序花费超过98%的时间用来做GC并且回收了不到2%的堆内存时,会抛出java.lang.OutOfMemoryError:GC overhead limit exceeded错误。具体的表现就是你的应用几乎耗尽所有可用内存,并且GC多次均未能清理干净

3. java.lang.OutOfMemoryError:Permgen space

方法区内存不足

  • 太多的类或者太大的类被加载到方法区中

4. java.lang.OutOfMemoryError:Metaspace

元空间内存不足

  • 太多的类或太大的类加载到元空间

5. java.lang.OutOfMemoryError:Unable to create new native thread

无法创建更多的线程

  • 当JVM向OS请求创建一个新线程时,而OS却无法创建新的native线程时就会抛出Unable to create new native thread错误

6. java.lang.OutOfMemoryError:Out of swap space

交换空间耗尽

  • Java应用程序在启动时会指定所需要的内存大小,可以通过-Xmx和其他类似的启动参数来指定。在JVM请求的总内存大于可用物理内存的情况下,操作系统会将内存中的数据交换到磁盘上去
  • 交换空间也将耗尽,并且由于缺少物理内存和交换空间,再次尝试分配内存也将失败

7. java.lang.OutOfMemoryError:Requested array size exceeds VM limit

应用程序试图分配大于Java虚拟机可以支持的数组

  • Java对应用程序可以分配的最大数组大小有限制。不同平台限制有所不同,但通常在1到21亿个元素之间。

8. Out of memory:Kill process or sacrifice child

可用虚拟内存(包括交换空间)消耗过多

  • 操作系统是建立在进程的概念之上,这些进程在内核中作业,其中有一个非常特殊的进程,名叫“内存杀手(Out of memory killer)”。当内核检测到系统内存不足时,OOM killer被激活,然后选择一个进程杀掉。哪一个进程这么倒霉呢?选择的算法和想法都很朴实:谁占用内存最多,谁就被干掉。

推荐阅读更多精彩内容