jvm溢出实现

java堆溢出

public class HeapOOM {
    static class OOMObject{

    }

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

}

设置参数

-Xms20m -Xmx20m -XX:+HeapDumpOnOutOfMemoryError
//-XX:+HeapDumpOnOutOfMemoryError 内存溢出时dump出当前内存转储快照以便分析

抛出异常

java.lang.OutOfMemoryError: Java heap space
Dumping heap to java_pid16032.hprof ...
Heap dump file created [28242928 bytes in 0.083 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3210)
    at java.util.Arrays.copyOf(Arrays.java:3181)
    at java.util.ArrayList.grow(ArrayList.java:261)
    at java.util.ArrayList.ensureExplicitCapacity(ArrayList.java:235)
    at java.util.ArrayList.ensureCapacityInternal(ArrayList.java:227)
    at java.util.ArrayList.add(ArrayList.java:458)
    at test1227.HeapOOM.main(HeapOOM.java:14)


虚拟机和本地方法栈溢出

栈溢出 -Xss设置栈容量大小
单线程只抛出stackoverflow异常

public class JavaVMStackSOF {
    private int stackLength=1;
    public void stackLeak(){
        stackLength++;
        stackLeak();
    }

    public static void main(String[] args) throws Throwable{
        JavaVMStackSOF oom=new JavaVMStackSOF();
        try {
            oom.stackLeak();
        }catch (Throwable e){
            System.out.println("stack length"+oom.stackLength);
            throw e;
        }
    }
}

设置参数-Xss128k 减少栈内存容量

stack length990
Exception in thread "main" java.lang.StackOverflowError
    at test1227.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:6)
    at test1227.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:7)
    at test1227.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:7)
    at test1227.JavaVMStackSOF.stackLeak(JavaVMStackSOF.java:7)

创建线程导致内存溢出异常
(不要在windows上执行这段代码)

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

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


方法区

/**
 * @description: VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M jdk1.6及之前版本
 * @author: icecrea
 * @create: 2018-10-17 17:22
 **/
public class RuntimeConstantPoolOOM {
    public static void main(String[] args) {
        //使用list保持常量池引用,避免full gc回收常量池行为
        List list=new ArrayList<>();
        //10MB的PermSize在integer范围足够产生OOM
        int i=0;
        while(true){
            list.add(String.valueOf(i++).intern());
        }
    }
}

使用Cglib使方法区出现内存溢出异常
在动态生成大量class的应用中,注意类的回收状况。这类场景除cglib字节码增强和动态语言外,还有大量jsp或动态产生jsp文件的应用

/**
 * @description:  VM Args:-XX:PermSize=10M -XX:MaxPermSize=10M
 * @author: icecrea
 * @create: 2018-10-17 17:47
 **/
public class JavaMethodAreaOOM {
    public static void main(final String[] args) {
        while (true){
            Enhancer enhancer=new Enhancer();
            enhancer.setSuperclass(HeapOOM.OOMObject.class);
            enhancer.setUseCache(false);
            enhancer.setCallback(new MethodInterceptor() {
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    return methodProxy.invokeSuper(o,args);
                }
            });
            enhancer.create();
        }
    }

    static class OOMObject{

    }
}

本机直接内存溢出

/**
 * @description: -Xmx20M -XX:MaxDirectMemorySize=10M
 * @author: icecrea
 * @create: 2018-10-17 17:57
 **/
public class DirectMemoryOOM {
    private static final int _1MB=1024*1024;

    public static void main(String[] args) throws IllegalAccessException {
        Field unsafeField= Unsafe.class.getDeclaredFields()[0];
        unsafeField.setAccessible(true);
        Unsafe unsafe=(Unsafe)unsafeField.get(null);
        while(true){
            unsafe.allocateMemory(_1MB);
        }
    }
}

你可能感兴趣的:(jvm溢出实现)