JAVA内存溢出异常测试

本文章为看《深入理解JAVA虚拟机》的笔记

  1. JAVA堆异常溢出:
/**
 * Vm args:-Xms20M -Xmx20M -XX:+HeapDumpOnOutOfMemoryError
 * 堆的最小值参数-Xms,堆的最大值参数-Xmx
 * -XX:+HeapDumpOnOutOfMemoryError表示让虚拟机在出现内存异常时Dump出当前的内存对快照
 * java 堆内存溢出测试,深入理解java虚拟机 p51
 * @author Rail
 *
 */
public class HeapOutOfMemoryError {

    static class OutOfMemoryError{
    }
    public static void main(String[] args) {
        List list = new ArrayList();
        while(true){
            list.add(new OutOfMemoryError());
        }
    }

}

运行结果:

java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid4208.hprof …
Heap dump file created [1029185391 bytes in 10.681 secs]

2.JAVA虚拟机栈和本地方法栈溢出:

1) 在Hotspot中,不区分JAVA虚拟机栈和本地方法栈。在JAVA虚拟机规范中描述了两种与之相关的异常:

  • 如果线程请求的栈深度超出了虚拟机允许的最大深度,将抛出StackOverflowError异常,测试代码:
/**
 * VM args:-Xss128k
 * -Xss128k 减小栈内存至128k
 * @author Rail
 *
 */
public class JavaVMStackOverFlowError {
    private int stackLength = 1;
    public void stackLeak(){
        stackLength++;
        stackLeak();
    }
    public static void main(String[] args){
        JavaVMStackOverFlowError sof = new JavaVMStackOverFlowError();
        try{
            sof.stackLeak();
        }catch(Throwable e){
            System.out.println("stackLength: "+sof.stackLength);
            throw e;
        }
    }
}

打印结果:

stackLength: 989
Exception in thread “main” java.lang.StackOverflowError
at jvm.JavaVMStackOverFlowError.stackLeak(JavaVMStackOverFlowError.java:11)

  • 如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError,测试代码:
/**
 * VM args:-Xss2M
 * 该程序执行容易死机,我的电脑运行死机两次
 * @author Rail
 *
 */
public class JavaVMStatckOutOfMemoryError {

    public void dontStop(){
        while(true){    
        }
    }
    public void stackLeakByThread(){
        while(true){
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    dontStop();
                }
            });
            t.start();
        }
    }

    public static void main(String[] args) {
        JavaVMStatckOutOfMemoryError sofm = new JavaVMStatckOutOfMemoryError();
        sofm.stackLeakByThread();
    }

}

运行结果,本人电脑运行时死机两次,未成功输出结果,在书上的输出结果为:

Exception in thread main java.lang.OutOfMemoryError:unable to create new native thread

3.方法区和运行时常量池溢出:

/**
 * VM args:-XX:PermSize10M -XX:MaxPermSize=10M
 * PermSize 方法区大小
 * @author Rail
 *
 */
public class RuntimeContantPoolOutOfMemoryError {

    public static void main(String[] args) {
        //保存对常量池字符串的应用,避免Full GC回收常量池的行为
        List list = new ArrayList();
        //10M在int的范围足够产生OutOfMemoryError
        int i = 0;
        while(true){
            list.add(String.valueOf(i++));
        }
    }

}

运行结果,在jdk6及之前,常量池分配在永久代内,通过-XX:PermSize10M -XX:MaxPermSize=10M限制其大小,而:

Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
at java.lang.Integer.toString(Integer.java:401)
at java.lang.String.valueOf(String.java:3087)
at jvm.RuntimeContantPoolOutOfMemoryError.main(RuntimeContantPoolOutOfMemoryError.java:17)
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option PermSize10M; support was removed in 8.0
Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=10M; support was removed in 8.0

你可能感兴趣的:(jvm)