OOM (Out Of Memory) 常见原因总结

"OOM" (Out Of Memory) 是指程序在运行过程中因为内存不足而引发的错误。在 Java 中,这种错误通常表现为 Out Of Memory Error。OOM 可以发生在不同的内存区域,具体原因取决于程序的运行情况和内存分配策略。

1、Java 堆空间溢出 (Heap Space OOM)

原因
  • 对象过多:程序创建了大量对象,且这些对象的生命周期较长,导致垃圾回收器无法及时回收足够的空间。

  • 大对象:程序创建了大量较大的对象,如大型数组或字符串,消耗大量连续内存。

  • 内存泄漏:程序中存在不再使用的对象,但由于引用链的存在导致垃圾收集器无法回收这些对象。

  • 显式内存分配:程序中使用 new 关键字显式分配内存,但未适当管理,导致内存耗尽。

  • 垃圾回收效率低:由于某些原因(如内存碎片化、垃圾回收算法效率低下等),垃圾回收器无法有效回收内存。

示例
 public class HeapSpaceOOM {
     public static void main(String[] args) {
         List<byte[]> list = new ArrayList<>();
         while (true) {
             list.add(new byte[1024 * 1024]); // 分配 1MB 的字节数组
         }
     }
 }

2、元数据空间溢出 (Metaspace OOM)

原因
  • 类加载过多:程序加载了大量类,超过了 Metaspace 的容量限制。

  • 类加载器泄漏:由于类加载器的引用链存在,导致已经加载的类无法被卸载。

  • 动态代理:使用动态代理框架(如 CGLIB 或 Javassist)生成大量类。

  • 反射操作:频繁使用反射操作加载类。

示例
 public class MetaspaceOOM {
     public static void main(String[] args) {
         int count = 0;
         try {
             while (true) {
                 Class.forName("com.example.MyClass" + count++);
             }
         } catch (ClassNotFoundException e) {
             e.printStackTrace();
         }
     }
 }

3、线程栈溢出 (Thread Stack OOM)

原因
  • 递归调用过深:方法递归调用层次过深,超过了线程栈的深度限制。

  • 线程数量过多:创建了大量线程,每个线程都占用一定的栈空间。

  • 线程栈大小设置不当:线程栈大小设置过大或过小,不适合实际需要。

示例
 public class ThreadStackOOM {
     public static void main(String[] args) {
         threadStackOOM();
     }
 ​
     private static void threadStackOOM() {
         threadStackOOM();  // 无限递归
     }
 }

4、直接内存溢出 (Direct Memory OOM)

原因
  • 直接内存分配过多:通过 ByteBuffer.allocateDirect() 等方法分配了大量直接内存。

  • 直接内存管理不当:分配的直接内存没有得到适当的释放。

示例
 import java.nio.ByteBuffer;
 ​
 public class DirectMemoryOOM {
     public static void main(String[] args) {
         while (true) {
             ByteBuffer.allocateDirect(1024 * 1024); // 分配 1MB 的直接内存
         }
     }
 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值