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

it2024-08-03  39

关于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); } } }
最新回复(0)