当前位置:网站首页>jvm内存溢出练习记录

jvm内存溢出练习记录

2022-06-09 10:34:00 lucky_tom

理解多少写多少,多删少补当勤奋

练习目标:

对jvm的几种常见的内存溢出进行回顾练习


内存溢出的类别:

  1. 堆溢出 - java.lang.OutOfMemoryError: Java heap space
  2. 栈溢出 - java.lang.StackOverflowError
  3. 栈溢出 - java.lang.OutOfMemoryError
  4. 方法区(元数据空间)溢出 - java.lang.OutOfMemoryError: Metaspace
  5. 直接内存溢出 - java.lang.OutOfMemoryErrorDirect buffer memory

堆溢出

最常见也是最容易遇到的OOM,一直在创建对象过多且GC无法回收,超过jvm堆的空间参数上限。


/** * -Xms1m -Xmx1m -XX:+PrintGCDetails */
public class HeapOOM {
    

    byte[] bytes;

    public HeapOOM() {
    
        bytes = new byte[1024];
    }

    public static void main(String[] args) throws Throwable{
    

        ArrayList<HeapOOM> heapOOMS = new ArrayList<>();
        int space = 10240;
        for (int i = 0; i < space; i++) {
    
            heapOOMS.add(new HeapOOM());
        }

    }

}


Exception in thread “main” java.lang.OutOfMemoryError: Java heap space
at HeapOOM.(HeapOOM.java:11)
at HeapOOM.main(HeapOOM.java:19)

栈溢出1

第一种,单个栈内申请的空间超过jvm限制的上限(冰箱里面的啤酒瓶爆炸)

/** * -Xss1m */
public class JVMStackOOM {
    


    private byte[] bytes = new byte[1024];


    public void func(){
    

        while (true){
    
            new Thread(() -> {
    
                try {
    
                    Thread.sleep(60*60*1000);
                } catch (InterruptedException e) {
    
                    e.printStackTrace();
                }
            }).start();
        }
    }

    public static void main(String[] args) {
    
        JVMStackOOM jvmStackOOM = new JVMStackOOM();
        jvmStackOOM.func();
    }

Exception in thread “main” java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:717)
at JVMStackOOM.func(JVMStackOOM.java:19)
at JVMStackOOM.main(JVMStackOOM.java:25)

栈溢出2

第二种,单个栈内申请的空间超过jvm限制的上限(冰箱堆满了啤酒瓶,冰箱爆炸)

/** * -Xss1m */
public class JVMStackOverFlow {
    

    public void func(){
    
        func();
    }

    public static void main(String[] args) throws Throwable{
    
        JVMStackOverFlow jvmStackOverFlow = new JVMStackOverFlow();
        jvmStackOverFlow.func();
    }


}

Exception in thread “main” java.lang.StackOverflowError
at JVMStackOverFlow.func(JVMStackOverFlow.java:7)

方法区溢出

大多数由于类加载过多(常见反射)超过jvm规定的上限。

需要引用 cglib.jar

/** * -XX:MaxMetaspaceSize=10M -XX:MetaspaceSize=10M */
public class MetaspaceOOM {
    

    public int age;
    public String name;

    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(o,args);
                }
            });
            enhancer.create();
        }
    }

    static class OOMObject {
    

    }

Caused by: java.lang.OutOfMemoryError: Metaspace
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:756)

直接内存溢出

如果使用MaxDirectMemorySize限制,若超过这个,就溢出。
如果没有MaxDirectMemorySize限制,超过物理内存,就溢出。

/**

  • -Xmx20M -XX:MaxDirectMemorySize=10M
    */
    public class DirectoryMemoryOOM {

    public static void main(String[] args) {
    ByteBuffer.allocateDirect(1024102412);
    }

}


> Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory
	at java.nio.Bits.reserveMemory(Bits.java:694)
	at java.nio.DirectByteBuffer.<init>(DirectByteBuffer.java:123)
	at java.nio.ByteBuffer.allocateDirect(ByteBuffer.java:311)
	at DirectoryMemoryOOM.main(DirectoryMemoryOOM.java:10)

原网站

版权声明
本文为[lucky_tom]所创,转载请带上原文链接,感谢
https://blog.csdn.net/lucky_tom/article/details/109613461