转载于:OutOfMemoryError系列(2): GC overhead limit exceeded
java.lang.OutOfMemoryError: GC overhead limit exceeded 这种情况发生的原因是, 程序基本上耗尽了所有的可用内存, GC也清理不了。
原因分析
JVM抛出 java.lang.OutOfMemoryError: GC overhead limit exceeded 错误就是发出了这样的信号: 执行垃圾收集的时间比例太大, 有效的运算量太小. 默认情况下, 如果GC花费的时间超过 98%, 并且GC回收的内存少于 2%, JVM就会抛出这个错误。
注意, java.lang.OutOfMemoryError: GC overhead limit exceeded 错误只在连续多次 GC 都只回收了不到2%的极端情况下才会抛出。假如不抛出 GC overhead limit 错误会发生什么情况呢? 那就是GC清理的这么点内存很快会再次填满, 迫使GC再次执行. 这样就形成恶性循环, CPU使用率一直是100%, 而GC却没有任何成果. 系统用户就会看到系统卡死 - 以前只需要几毫秒的操作, 现在需要好几分钟才能完成。
这也是一个很好的 快速失败原则 的案例。
以下代码在无限循环中往 Map 里添加数据。 这会导致 “GC overhead limit exceeded” 错误:
package com.cncounter.rtime;
import java.util.Map;
import java.util.Random;
public class TestWrapper{
public static void main(String args[]) throwsException {
Map map = System.getProperties();
Random r =newRandom();
while(true) {
map.put(r.nextInt(),"value");
}
}
}