JVM - OOM可能发生在哪些区域上

时间:2023-11-21 10:34:51  热度:0°C

根据Java doc的描述,OOM是指JVM的内存不够用了,同时垃圾收集器也无法提供更多的内存。从描述中可以看出,在JVM抛出OutOfMemoryError之前,垃圾收集器一般会出马先尝试回收内存。

从上面分析的Java数据区来看,除了程序计数器不会发生OOM外,哪些区域会发生OOM的情况呢?

  • 堆内存,堆内存不足是最常见的发送OOM的原因之一。如果在堆中没有内存完成对象实例的分配,并且堆无法再扩展时,将抛出OutOfMemoryError异常,抛出的错误信息是“java/lang/OutOfMemoryError/Java heap space”。当前主流的JVM可以通过-Xmx和-Xms来控制堆内存的大小,发生堆上OOM的可能是存在内存泄露,也可能是堆大小分配不合理。

  • Java虚拟机栈和本地方法栈,这两个区域的区别不过是虚拟机栈为虚拟机执行Java方法服务,而本地方法栈则为虚拟机使用到的Native方法服务,在内存分配异常上是相同的。在JVM规范中,对Java虚拟机栈规定了两种异常:a/ 如果线程请求的栈大于所分配的栈大小,则抛出StackOverFlowError错误,比如进行了一个不会停止的递归调用;b/ 如果虚拟机栈是可以动态拓展的,拓展时无法申请到足够的内存,则抛出OutOfMemoryError错误。

  • 直接内存:直接内存虽然不是虚拟机运行时数据区的一部分,但既然是内存,就会受到物理内存的***。在JDK1/4中引入的NIO使用Native函数库在堆外内存上直接分配内存,但直接内存不足时,也会导致OOM。

  • 方法区:随着Metaspace元数据区的引入,方法区的OOM错误信息也变成了“java/lang/OutOfMemoryError/Metaspace”

  • 对于旧版本的Oracle JDK,由于永久代的大小有限,而JVM对永久代的垃圾回收并不积极,如果往永久代不断写入数据,例如String/Intern()的调用,在永久代占用太多空间导致内存不足,也会出现OOM的问题,对应的错误信息为“java/lang/OutOfMemoryError/PermGen space”

  • 内存区域

    免责声明:
    1. 《JVM - OOM可能发生在哪些区域上》内容来源于互联网,版权归原著者或相关公司所有。
    2. 若《65667893文库网》收录的文本内容侵犯了您的权益或隐私,请立即通知我们删除。