在JVM的几个内存区域中,除了程序计数器外,其他几个运行时区域都有发生内存溢出(OOM)异常的可能,重点关注堆和栈。

Java堆溢出

Java堆用于储存对象实例,只要不断创建不可被回收的对象,比如静态对象,那么随着对象数量的增加,总容量触及最大堆的容量限制后就会产生内存溢出异常(OutOfMemoryError)。

这就相当于一个房子里,不断堆积不能被收走的杂物,那么房子很快就会被堆满了。

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

虚拟机栈.OutOfMemoryError

JDK使用的HotSpot虚拟机的栈内存大小是固定的,我们可以把栈的内存设大一点,然后不断地去创建线程,因为操作系统给每个进程分配的内存是有限的,所以到最后,也会发生OutOfMemoryError异常。

public class JavaVMStackOOM {
  private void dontStop() {
    while (true) {
    }
  }
  public void stackLeakByThread() {
    while (true) {
    Thread thread = new Thread(new Runnable() {
      public void run() {
      dontStop();
      }
  	});
  thread.start();
  	}
  }
  public static void main(String[] args) throws Throwable {
    JavaVMStackOOM oom = new JavaVMStackOOM();
    oom.stackLeakByThread();
  }
}