GC回收时间过长时会抛出OutOfMemoryError。过长的定义是:超过98%的时间用来做GC并且回收了不到2%的堆内存。

    连续多次GC都只回收了不到2%的极端情况下才会抛出。假如不抛出GC overhead limit错误会发生什么情况呢?

    那就是GC清理的这么点内存很快会再次填满,迫使GC再次执行,这样就会形成恶性循环,CPU使用率一直是100%,而GC却没有任何成果

    示例代码:
    1. public class GCOverheadLimitExceededDemo {
    2. public static void main(String[] args) {
    3. int i = 0;
    4. List<String> list = new ArrayList<String>();
    5. try {
    6. while (true) {
    7. list.add(String.valueOf(++i).intern());
    8. }
    9. } catch (Throwable e) {
    10. System.out.println("*********************i:" + i);
    11. e.printStackTrace();
    12. throw e;
    13. }
    14. }
    15. }
    因为本机内存较大,手动设置堆内存大小为10M,最大直接内存为5m -Xmx10M -Xms10M -XX:MaxDirectMemorySize=5m -XX:+PrintGCDetails

    Java虚拟机OOM之GC overhead limit exceeded - 图1

    查看运行结果:

    Java虚拟机OOM之GC overhead limit exceeded - 图2