首先OOM发生在线程申请内存资源时,申请不到而抛出来的异常。所以OOM肯定是在某一条线程上执行到某一条指令,去申请内存获取不到时抛出来的。

那我们是否可以构造一条线程,它不停地申请内存资源,但是引用着不让Full GC释放它,然后try catch这段代码,捕获OOM异常,但不处理。伪代码如下:

起一条线程 {
    List<Object> list = new ArrayList();
    while(true) {
        try {
            while(true) {
                try {
                    list.add(new byte[100]); // 一直申请内存
                } catch(Throwable e) {
                    // 这里没有任何代码,捕获异常但不处理
                    // 假设这里有任何代码,这些代码本身也可能抛OOM,即便是最简单的System.out.println
                }
            }
        }
    }
}

完整的代码详见j2se项目的TestMemory3.java代码。

实验结论:

确实可以捕获OOM异常而不退出,此时整个java进程一直在FullGC,但是不会退出。

文档更新时间: 2020-08-21 17:07   作者:nick