引言

在开发过程中,因为编程经验不足,经常会导致各种各样的溢出,今天本文就举例说明几种常见的溢出

堆溢出

堆溢出是最常见的一种溢出。
导致原因:堆中没有足够的空间储存新生成的实例对象

public static void main(String[] args) {
       List<TestCase> cases = new ArrayList<TestCase>();
       while(true){
           cases.add(new TestCase());
       }
    }

解决办法:调大堆空间大小

-Xmx2048M

栈溢出

导致原因:方法调用太深,每执行一个方法,就有一次进栈操作,方法执行完就会出栈,无边界递归调用就会导致此问题

 public void plus() {
       i++;
       plus();
    }

此方法一旦被调用就会产生栈溢出

常量池溢出

导致原因:常量池空间有限,无法储存更多的常量了

    public static void main(String[] args) throws Exception {
        try {
            List<String> strings = new ArrayList<String>();
            int i = 0;
            while (true) {
                strings.add(String.valueOf(i++).intern());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
    }

方法区溢出

方法区用来储存类定义信息
导致原因:大量的动态类生成,导致方法区空间不足

    public static void main(String[] args) {
        while (true) {
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(TestCase.class);
            enhancer.setUseCache(false);
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
                    return arg3.invokeSuper(arg0, arg2);
                }
            });
            enhancer.create();
        }
    }

直接内存溢出

通过Unsafe在直接内存分配空间
导致原因:直接内存不足

    public static void main(String[] args) {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            Unsafe unsafe = (Unsafe) field.get(null);
            while (true) {
                unsafe.allocateMemory(ONE_MB);
                count++;
            }
        } catch (Exception e) {
            System.out.println("Exception:instance created " + count);
            e.printStackTrace();
        } catch (Error e) {
            System.out.println("Error:instance created " + count);
            e.printStackTrace();
        }
    }