(转)JVM中那些区域会发生OOM?

JVM中程序计数器是唯一不会OOM的! 

### JVM 内存区域及其触发 OutOfMemoryError 的可能性 #### 1. **堆内存 (Heap Memory)** 堆内存是 JVM 中最大的一块内存区域,用于存储对象实例。当堆内存不足以分配新对象,并且垃圾回收器无法释放足够的空间时,就会抛出 `OutOfMemoryError` 错误[^4]。 典型场景包括:频繁创建大对象、内存泄漏或者设置了过小的堆大小(通过 `-Xmx` 参数控制最大堆大小)。 ```java // 创建超大数据结构可能导致堆内存溢出 List<byte[]> list = new ArrayList<>(); while (true) { list.add(new byte[1024 * 1024]); // 每次增加1MB数据 } ``` --- #### 2. **方法区 / 元空间 (Metaspace)** 在 JDK 8 及之后版本中,永久代被移除并替换为元空间。元空间主要用于存储类的元信息(如字节码、运行时常量池等)。如果应用程序加载了大量的类文件而未设置合适的元空间上限,则可能会引发 `OutOfMemoryError: Metaspace` 错误[^3]。 常见情况有动态代理框架(如 Spring AOP)、OSGi 容器或微服务架构下频繁加载卸载模块的情况。 ```java // 动态生成大量类可能引起元空间溢出 for (int i = 0; i < Integer.MAX_VALUE; i++) { ClassLoader loader = new CustomClassLoader(); loader.loadClass("com.example.Class" + i); } ``` --- #### 3. **栈内存 (Stack Memory)** 每个线程都有自己的私有栈,用于保存局部变量表和操作数栈等内容。如果单个线程的方法嵌套层次太深或存在无限递归,就可能出现 `StackOverflowError`;但如果线程数量过多且每个线程占用较大的栈空间,则会因总栈容量不足而导致 `OutOfMemoryError`[^5]。 可以通过调整 `-Xss` 参数来改变每个线程的最大栈大小。 ```java // 无限递归导致栈溢出 public void recursiveMethod() { recursiveMethod(); // 调用自身直到耗尽栈空间 } recursiveMethod(); ``` --- #### 4. **本地直接内存 (Direct Memory)** 除了 Java 堆之外,程序还可以通过 `ByteBuffer.allocateDirect()` 分配非堆内存(即本地直接内存),这部分不受 JVM 堆管理约束。然而,默认情况下它的总量受到物理内存限制以及由参数 `-XX:MaxDirectMemorySize` 控制的阈值影响。一旦超出该范围便会报告 `OutOfMemoryError: Direct buffer memory` 错误。 ```java import java.nio.ByteBuffer; public class DirectMemoryTest { public static void main(String[] args) throws Exception { while (true) { ByteBuffer buf = ByteBuffer.allocateDirect(1024 * 1024); // 占用1MB直连缓冲区 } } } ``` --- #### 5. **本机内存 (Native Memory)** 虽然严格意义上不属于 JVM 自身定义的部分,但在实际应用过程中,诸如 JNI 或者第三方库也可能消耗大量的本机资源从而间接造成 OOM 现象。例如某些图像处理工具包需要额外申请外部缓存区完成渲染工作却未能及时释放这些临时占位符的话同样容易陷入困境之中。 --- ### 总结 综上所述,JVM 主要有以下几个部分会发生 `OutOfMemoryError`: - 堆内存 (`OutOfMemoryError: Java heap space`) - 方法区/元空间 (`OutOfMemoryError: Metaspace`) - 栈内存 (`OutOfMemoryError: unable to create new native thread`) - 直接内存 (`OutOfMemoryError: Direct buffer memory`) - 本机内存 (依赖具体实现) 需要注意的是,默认行为并非等到完全耗尽才返回错误消息——只要检测到性能下降严重至不可接受程度即可提前终止进程以保护整体稳定性[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值