jvm中会发生outofmemoryerror的内存区域有四个:堆、元空间(方法区)、虚拟机栈、本地方法栈。堆最常见,报错为“java heap space”,主因是内存泄漏或堆配置不足;元空间报错为“metaspace”,多由动态类加载或类加载器泄漏引发;虚拟机栈和本地方法栈oom表现为“unable to create native thread”,通常因线程数过多或-xss过大导致系统资源耗尽;程序计数器是唯一不会发生oom的区域。

JVM中会发生OutOfMemoryError的内存区域有四个:堆、元空间(方法区)、虚拟机栈、本地方法栈。
堆(Heap)
这是最常发生OutOfMemoryError的地方。错误信息为:java.lang.OutOfMemoryError: Java heap space。
- 对象持续创建且无法被回收(比如被静态集合长期持有、缓存未清理、监听器未注销);
- 应用实际需要的堆内存超过-Xmx设定值(如处理大报表、批量导入、图像解析);
- 堆参数配置过小,而业务负载未同步评估调整。
元空间(Metaspace)
JDK 8+ 中替代永久代的区域,错误信息为:java.lang.OutOfMemoryError: Metaspace。
- 大量动态生成类(如使用CGLib代理、Spring AOP、模板引擎如Thymeleaf/JSP);
- 热部署频繁导致旧类加载器未卸载,元数据持续累积;
- 显式设置了过小的
-XX:MaxMetaspaceSize,或系统物理内存不足限制了本地内存分配。
虚拟机栈(JVM Stack)
每个线程私有,错误信息通常是:java.lang.OutOfMemoryError: unable to create new native thread。
- 创建线程数过多(如线程池无界、短生命周期任务滥用new Thread());
- 单线程栈过大(-Xss设置过高),在堆和元空间占用较大时,留给线程创建的地址空间不足;
- 操作系统级限制(如Linux默认ulimit -u、Windows进程用户态地址空间约2GB)被触及。
本地方法栈(Native Method Stack)
与虚拟机栈作用类似,服务于JNI调用。虽然HotSpot中常与Java栈共用内存,但在某些JVM实现或大量本地调用场景下,也可能独立触发OOM,表现形式与虚拟机栈溢出一致。
程序计数器是唯一不会发生OutOfMemoryError的区域——它只存储一个字节码行号,空间极小且线程独享,规范明确排除OOM可能。











