jvm 实现运行常见内存溢出

时间:2021-07-21 20:56:54

1.       堆溢出

Java堆内存存储对象实例,故溢出只需要疯狂的创建对象即可,但因为回收,需要链表引用防止回收

public class HeapOOM {

   public static void main(String[] args) {

// 因为会被回收,所以搞个list引用他们,则存在

      List<Object> list = new ArrayList<Object>();

      int i = 0;

      while (true) {

          list.add(new Integer(i++));

      }

   }

}

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

栈中存储的线程对应的方法入栈,故不断的递归即可

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;

      }

   }

}

 

3.       方法区和动态常量池溢出

因为方法区存的是动态常量、class对象等,故需要溢出的话就是疯狂的插入动态常量或创建class对象即可

a)      插入动态常量

public class RuntimeConstantPoolOOM {

   public static void main(String[] args) {    

      // 使用List保持着常量池引用,避免Full GC回收常量池行为

      List<String> list = new ArrayList<String>();

      // 10MB的PermSize在integer范围内足够产生OOM了

      int i = 0;

      while (true) {

          list.add(String.valueOf(i++).intern());

      }

   }

}

b)     使用cglib创建class

4.       本机直接内存溢出

直接内存就是读取文件的时候,故直接读取一个大文件即可