// Java program to illustrate
// Heap error
import java.util.*;
public class Heap {
static List list = new ArrayList();
public static void main(String args[]) throws Exception {
Integer[] array = new Integer[10000 * 10000];
}
}
解决方案
- 检查是否存在大对象分配,或者大数组分配
- jmap dump下来在使用mat工具分析看是否有内存泄漏
- 加大-Xmx内存
- 还有一点容易被忽略,检查是否有大量的自定义的 Finalizable 对象,也有可能是框架内部提供的,考虑其存在的必要性
-
- Error 2 GC Overhead limit exceeded
这个主要说明了JVM的GC一直在运行,并且程序已经运行很慢。通常98%的时间在做GC,那么这个时候会抛出这个异常
``` java
// Java program to illustrate
// GC Overhead limit exceeded
import java.util.*;
public class Wrapper {
public static void main(String args[]) throws Exception
{
Map m = new HashMap();
m = System.getProperties();
Random r = new Random();
while (true) {
m.put(r.nextInt(), "randomValue");
}
}
}
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.lang.Integer.valueOf(Integer.java:832)
at Wrapper.main(error.java:9)
Error 3 - Permgen space is thrown
java内存分为不同的区域,包括permgen area都是在JVM启动的时候指定的,这个通常是说方法区的内存太小导致的。比如加载的class超过了这个区域指定的大小
// Java program to illustrate
// Permgen Space error
import javassist.ClassPool;
public class Permgen {
static ClassPool classPool = ClassPool.getDefault();
public static void main(String args[]) throws Exception
{
for (int i = 0; i < 1000000000; i++) {
Class c = classPool.makeClass(com.saket.demo.Permgen" + i).toClass();
System.out.println(c.getName());
}
}
}
可以通过修改以下参数调整
> java -XX:MaxPermSize=512m com.saket.demo.Permgen(这个已经在JAVA8 中废弃了)
- Error 4 - Metaspace
java 类元数据是分配在native 内存中的,如果这个部分的内存超出,也会抛出OOM。
``` java
// Java program to illustrate
// Metaspace error
import java.util.*;
public class Metaspace {
static javassist.ClassPool cp = javassist.ClassPool.getDefault();
public static void main(String args[]) throws Exception
{
for (int i = 0; i < 100000; i++) {
Class c = cp.makeClass("com.saket.demo.Metaspace" + i).toClass();
}
}
}
Java OOM归类
内存模型
public class Heap { static List list = new ArrayList();
public static void main(String args[]) throws Exception {
Integer[] array = new Integer[10000 * 10000];
}
}
如果你用java -Xmx100m -XX:+UseParallelGC 来运行上面的代码,那么这个错误就会抛出
Sun 官方对此的定义:超过98%的时间用来做GC并且回收了不到2%的堆内存时会抛出此异常。
解决方法 1、检查项目中是否有大量的死循环或有使用大内存的代码,优化代码。 2、添加参数 -XX:-UseGCOverheadLimit 禁用这个检查,其实这个参数解决不了内存问题,只是把错误的信息延后,最终出现 java.lang.OutOfMemoryError: Java heap space。 3、dump内存,检查是否存在内存泄露,如果没有,加大内存。
public class Permgen { static ClassPool classPool = ClassPool.getDefault();
public static void main(String args[]) throws Exception { for (int i = 0; i < 1000000000; i++) { Class c = classPool.makeClass(com.saket.demo.Permgen" + i).toClass(); System.out.println(c.getName()); } } }
这段代码持续生成新类并且加载到元数据空间中,直到完全用完元数据空间,然后就会抛出java.lang.OutOfMemoryError: Metaspace。
解决方法 因为该OOM原因比较简单,解决方法有如下几种: 1、检查是否永久代空间或者元空间设置的过小 ( -XX:MaxMetaspaceSize) 2、检查代码中是否存在大量的反射操作 3、dump之后通过mat检查是否存在大量由于反射生成的代理类 4、放大招,重启JVM
Error 5 – Requested array size exceeds VM limit : 主要表示应用尝试分配一个数组大于堆的大小,就会报出这个错误,举个栗子,比如在512的内存对空间中,尝试分配一个1024M的数组就会抛出这样的错误
Error 6 – Request size bytes for reason. Out of swap space? java.lang.OutOfMemoryError: Out of swap space 通常是由以下的原因造成的:
Error 7 : reason stack_trace_with_native_method
public class GFG { public static void main(String args[]) throws Exception { while (true) { new Thread(new Runnable() { public void run() { try { Thread.sleep(1000000000); } catch (InterruptedException e) { } } }).start(); } } }