赞
踩
在Java应用程序开发中,OutOfMemoryError(OOM)是一个令人头痛的问题。当JVM中的内存无法满足应用程序的需求时,就会抛出这个错误。本文将深入探讨OOM的三大场景:堆内存溢出、方法区内存溢出和栈内存溢出,并分析它们的原因,提供相应的实战解决方案。
OOM 的全称是 Out Of Memory,那我们的内存区域有哪些会发生 OOM 呢?我们可以从内存区域划分图上,看一下彩色部分
可以看到除了程序计数器,其他区域都有OOM溢出的可能。但是最常见的还是发生在堆内存溢出、方法区内存溢出和栈内存溢出,主要是在堆上。
另外,我们常说的 OOM 异常,其实是 Error
Java 堆用于存储对象实例,我们只要不断的创建对象,并且保证 GC Roots 到对象之间有可达路径来避免 GC 清除这些对象,那随着对象数量的增加,总容量触及堆的最大容量限制后就会产生内存溢出异常。
Java 堆内存的 OOM 异常是实际应用中最常见的内存溢出异常。
/**
* JVM参数:-Xmx10m
*/
public class JavaHeapSpaceDemo {
static final int SIZE = 100 * 1024 * 1024;
public static void main(String[] a) {
int[] i = new int[SIZE];
}
}
代码试图分配容量为 100M 的 int 数组,如果指定启动参数 -Xmx10m,分配内存就不够用,就类似于将 XXXL 号的对象,往 S 号的 Java heap space 里面塞。
针对大部分情况,通常只需要通过 -Xmx 参数调高 JVM 堆内存空间即可。如果仍然没有解决,可以参考以下情况做进一步处理:
栈内存溢出通常与线程的执行和递归调用有关。
public class StackOverflowErrorDemo {
public static void main(String[] args) {
javaKeeper();
}
private static void javaKeeper() {
javaKeeper();
}
}
修复引发无限递归调用的异常代码, 通过程序抛出的异常堆栈,找出不断重复的代码行,按图索骥,修复无限递归 Bug
排查是否存在类之间的循环依赖
通过 JVM 启动参数 -Xss 增加线程栈内存空间, 某些正常使用场景需要执行大量方法或包含大量局部变量,这时可以适当地提高线程栈空间限制
方法区内存溢出通常与类的加载和元数据的存储有关。
JDK 1.8 之前会出现 Permgen space,该错误表示永久代(Permanent Generation)已用满,通常是因为加载的 class 数目太多或体积太大。随着 1.8 中永久代的取消,就不会出现这种异常了。
Metaspace 是方法区在 HotSpot 中的实现,它与永久代最大的区别在于,元空间并不在虚拟机内存中而是使用本地内存,但是本地内存也有打满的时候,所以也会有异常。
/** * JVM Options: -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m */ public class MetaspaceOOMDemo { public static void main(String[] args) { while (true) { Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(MetaspaceOOMDemo.class); enhancer.setUseCache(false); enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> { //动态代理创建对象 return methodProxy.invokeSuper(o, objects); }); enhancer.create(); } } }
借助 Spring 的 GCLib 实现动态创建对象
Exception in thread "main" org.springframework.cglib.core.CodeGenerationException: java.lang.OutOfMemoryError-->Metaspace
方法区溢出也是一种常见的内存溢出异常,在经常运行时生成大量动态类的应用场景中,就应该特别关注这些类的回收情况。这类场景除了上边的 GCLib 字节码增强和动态语言外,常见的还有,大量 JSP 或动态产生 JSP 文件的应用(远古时代的传统软件行业可能会有)、基于 OSGi 的应用(即使同一个类文件,被不同的加载器加载也会视为不同的类)等。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。