一次JVM实验
在一次JAVA堆内存的OOM实验中,程序抛出了GC overhead limit exceeded信息。
查阅了网上的资料,总结一下,这是由于GC频繁导致的,由于内存的不足,频繁的GC,甚至影响到正常的程序执行,即所谓的98%资源用于GC,回收不到2%的可用内存,这样很明显是程序的问题。GC认为内存中的数据都是需要的,但是程序执行所需的内存不足,只能不停的GC,最后抛出这样的错误。
咋办呢?
①修改程序,查看当前堆中的对象是否是必须的,将不需要的及时回收(obj == null //help GC)
②修改堆的内存大小
再回到实验
这是一个失败的实验,因为最终是因为java中的nio分配的直接内存抛出的,而不是因为java堆内存抛出的。不多说,贴异常and代码。
public class HeapOOM {
static class OOMDemo{
public OOMDemo(){
byte[] bytes = new byte[2048];
System.out.println("---");
}
}
public static void main(String[] args) {
List<OOMDemo> list = new ArrayList<>();
while(true){
list.add(new OOMDemo());
}
}
}
/*异常信息*/
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.nio.CharBuffer.wrap(CharBuffer.java:373)
at sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:265)
at sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.io.OutputStreamWriter.write(OutputStreamWriter.java:207)
at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:129)
at java.io.PrintStream.newLine(PrintStream.java:545)
at java.io.PrintStream.println(PrintStream.java:807)
at com.csii.wuw.oom.HeapOOM$OOMDemo.<init>(HeapOOM.java:10)
at com.csii.wuw.oom.HeapOOM.main(HeapOOM.java:17)
当然,在调整了JVM参数,还是如愿的抛出了OOM:Java heap space。-Xms1m -Xmx1m。
使用jhat分析了一下转储的dump文件
上图很明显,引用了很多OOMDemo实例,导致了OOM。