优秀的编程知识分享平台

网站首页 > 技术文章 正文

OutOfMemoryError异常(outofmemoryexception异常)

nanyue 2024-10-12 05:45:32 技术文章 6 ℃

我们知道在Java虚拟机内存中,除了程序计数器外,其它的内存区域都可能会发生OutOfMemoryError异常。本文将用具体的事例来演示在什么情况下会出现OutOfMemoryError异常,并以此来演示一下相关的虚拟机参数。

  • 堆溢出

我们知道Java堆是用来存储对象实例的,只要我们不断的创建对象,并保证它们不被Java垃圾回收器回收,当存储的对象数量超过Java堆中最大的容量时,就会抛出OutOfMemoryError异常。在Java虚拟机中可以用-Xms参数和-Xmx参数设置Java堆的容量大小。

-Xms // 设置堆的最小值

-Xmx // 设置堆的最大值

当-Xms和-Xmx参数不一致时,如果存储的对象超过-Xms时,Java堆将进行自动扩展。下面我们将-Xms和-Xmx设置为一致,以避免Java堆的自动扩展,方便我们演示Java堆的溢出。

  • 栈溢出

栈的容量由参数-Xss设置。在Java栈中有两种情况可能会抛出异常

  1. 如果线程请求栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常
  2. 如果虚拟机在扩展栈时无法获得足够的内存空间时,则抛出OutOfMemoryError异常。

下面我们通过两个例子来演示上述的异常情况。

由此可见,在单线程的情况下,无论栈的大小是多少,当内存无法分配时,虚拟机都会抛出StackOverflowError异常。那如何才能抛出OutOfMemoryError异常呢?我们先看下面的例子,然后我们在做详细解释。

上述的代码不但会抛出OutOfMemoryError异常,还会导致系统卡死,所以要慎重执行上面代码。那为什么重复创建线程就会导致虚拟机栈内存的溢出呢?这是因为在其它文章中我们已经介绍过了,线程都有自己的独立内存空间,并且每个线程的内存空间大小是有限制的,如果创建的线程空间大小超过了系统内存时,如果继续创建线程,虚拟机无法为栈分配空间了,所以就会抛出OutOfMemoryError异常。

  • 方法区和运行时常量池

我们可以用下面的参数来设置方法区的大小

-XX:PermSize // 方法区设置的最小值
-XX:MaxPermSize // 方法区设置的最大值
  • 本机直接内存溢出

我们可以用下面参数指定本机容量,如果不设置默认与堆的最大值一样。

-XX:MaxDirectMemorySize
最近发表
标签列表