什么是OOM?它是如何产生的?代码举例讲解

OOM(OutOfMemoryError)是Java堆内存溢出异常。它是由JVM抛出的,表示程序试图申请的内存超出JVM容许的最大值。

OOM异常产生的主要原因有:

  1. Java堆内存溢出(Heap Space):对象实例太多,占用的Java堆内存超限。
  2. 永久代内存溢出(PermGen Space):类定义太多,占用的永久代内存超限。
  3. 本地方法栈溢出(StackOverflowError):栈帧嵌套过深,超出最大深度。
  4. 直接内存溢出(Direct buffer):申请的直接内存超出限制。

来看几个简单示例:

Heap Space:

public class OOMTest {
    public static void main(String[] args) {
        List<OOMTest> list = new ArrayList<>();
        while (true) {
            list.add(new OOMTest());
        }
    }
}

运行结果:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space

PermGen Space:

public class OOMTest {
    public static void main(String[] args) {
        while (true) {
            Enhancer.enhance(OOMTest.class, new MethodInterceptor() {
                public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) {
                    return proxy.invokeSuper(obj, args);
                }
            });
        }
    }
}

运行结果:

Exception in thread "main" java.lang.OutOfMemoryError: PermGen space 

StackOverflowError:

public class OOMTest {
    public static void main(String[] args) {
        main(args);
    }
}

运行结果:

Exception in thread "main" java.lang.StackOverflowError

所以,理解OOM异常可以让我们编写更健壮的程序,避免异常情况下的崩溃。