题目
哪些内存区域可能发生 OOM?每个区域发生 OOM 的原因有哪些
解释
类似问题如 “JVM 中哪个内存区域不会出现 OOM?”
答案
1)**堆**:如果在堆中没有内存来完成对象实例的分配,并且堆也无法再扩展时,JVM 就会抛出 OutOfMemoryError 异常 2)**方法区**: - JDK 8 之前的实现 - **永久代**:我们可以通过 `‑XX:MaxPermSize` 设置永久代的大小,一旦类的元数据超过了设定的大小,程序就会耗尽内存,并出现内存溢出错误 (`java.lang.OutOfMemoryError: PermGen space`)。 - JDK 8 及之后的实现 - **元空间**:「元空间存在于本地内存,意味着只要本地内存足够,它就不会 OOM」 3)**虚拟机栈 / 本地方法栈**:栈这个内存区域有两种异常状况: - 如果「线程请求的栈深度大于虚拟机所允许的深度」,将抛出 `StackOverflowError` 异常(栈溢出) - 如果使用的 JVM 支持动态扩展虚拟机栈容量的话,「当栈扩展时无法申请到足够的内存」就会抛出 `OutOfMemoryError` 异常(内存溢出) 4)**程序计数器**:此内存区域是唯一一个在《Java虚拟机规范》中【没有】规定任何 OutOfMemoryError(内存溢出)情况的区域