JVM面试题:代码实现OOM内存溢出 (包括堆内存、栈内存、云空间、本地直接内存)

关于JVM运行时数据区中各内存的Out Of Memory代码演示

1. 测试堆内存溢出

package OOM;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: Cool_Wu
 * @Date: 2020-10-20 20:27
 */

/**
 * 测试堆内存溢出:
 *  1.调整堆内存参数 VM options:-Xms20M -Xmx20M
 *  2.使用死循环不断地创建对象,通过List集合保持对象的引用,
 *    保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象
 *  运行结果:java.lang.OutOfMemoryError: Java heap space
 */
public class TestHeapOOM {

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

2.测试栈内存溢出

package OOM;

/**
 * @Author: Cool_Wu
 * @Date: 2020-10-20 21:13
 */

/**
 * 测试JVM栈内存溢出:
 *  1.调整栈内存参数 VM options:-Xss128K
 *  2.使用递归定义大量的本地变量,增加此方法栈帧中本地变量表的长度,导致栈内存泄漏
 *
 *  运行结果:Exception in thread "main" java.lang.StackOverflowError
 */
public class TestStackOOM1 {
    private static int stackLength = 1;

    public static void stackLeak(){
        stackLength++;
        stackLeak();
    }
    public static void main(String[] args) throws Throwable{
        try {
            stackLeak();
        }catch (Throwable e) {
            System.out.println("stackLength :" + stackLength);
            throw e;
        }
    }
}

package OOM;

/**
 * @Author: Cool_Wu
 * @Date: 2020-10-20 22:05
 */

/**
 1. 测试JVM栈内存溢出:(一个线程一个栈,栈内存设置越大,溢出越快)
 2.  1.调整栈内存参数 VM options:-Xss2M
 3.  2.通过死循环不断的创建线程,通过另一个死循环保持线程存活避免回收
 4.  5.  运行结果:Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
 */
public class TestStackOOM2 {
    public static void dontStop(){
        while (true){}
    }

    public static void main(String[] args) {
        while (true) {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    dontStop();
                }
            });
            thread.start();
        }
    }
}

3. 测试云空间内存溢出

package OOM;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * @Author: Cool_Wu
 * @Date: 2020-10-20 23:35
 */

/**
 * 测试元空间内存溢出:
 *  1.调整元空间参数值 VM options:-XX:MetaspaceSize=10M -XX:MaxMetaspaceSize=10M
 *  2.使用死循环不断地创建CGLib动态代理的class
 * 运行结果:Exception in thread "main" java.lang.OutOfMemoryError: Metaspace
 */
public class TestMetaOOM {
    static class OOMObject{}
    public static void main(String[] args) {
        while (true){
            Enhancer enhancer = new Enhancer();
            enhancer.setSuperclass(OOMObject.class);
            enhancer.setUseCache(false);
            enhancer.setCallback(new MethodInterceptor() {
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    return methodProxy.invokeSuper(objects,args);
                }
            });
            enhancer.create();
        }
    }
}

4. 测试本地直接内存溢出

package OOM;

import sun.misc.Unsafe;

import java.lang.reflect.Field;

/**
 * @Author: Cool_Wu
 * @Date: 2020-10-20 23:54
 */

/**
 * 测试本地直接内存溢出:
 *  1.调整直接内存参数值 VM options:-Xmx20M -XX:MaxDirectMemorySize=10M
 *  2.使用死循环不断地通过unsafe.allocateMemory()方法向操作系统申请分配内存
 *
 *  运行结果:Exception in thread "main" java.lang.OutOfMemoryError
 * 	        at sun.misc.Unsafe.allocateMemory(Native Method)
 */
public class TestDirectMemoryOOM {
    private static final int MB = 1024 * 1024;
    public static void main(String[] args) throws Exception{
        Field unsafeField = Unsafe.class.getDeclaredFields()[0];
        unsafeField.setAccessible(true);
        Unsafe unsafe = (Unsafe) unsafeField.get(null);
        while (true){
            unsafe.allocateMemory(MB);
        }
    }
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值