OutOfMemoryError异常
在JVM规范的描述中,除了程序计数器外,JVM内存的其他几个运行时数据区都有发生OutOfMemoryError异常的可能。
Java堆溢出导致OOM:
Java堆用于存储对象实例,只要不断地创建对象,并且保证GC Roots到对象之间有可达路径来避免垃圾回收机制清除这些对象,那么在对象数量到达最大堆的容量限制后就会产生内存溢出异常。
- 如果是内存泄露,可进一步通过工具查看泄露对象到GC Roots的引用链,找到泄露对象是通过怎样的路径与GC Roots相关联并导致垃圾收集器无法自动回收它们的。
- 如果不是内存泄露(对象有存在的必要,不能被回收),可以查看JVM的堆参数(-Xmx与-Xms),与机器物理内存对比看是否还可以调大,从代码上检查是否存在某些对象生命周期过长、持有状态时间过长的情况,尝试减少程序运行期的内存消耗。
- 将堆的最小值-Xms参数与最大值-Xmx参数设置为一样即可避免堆自动扩展。
- 通过参数-XX:+HeapDumpOnOutOfMemoryError可以让虚拟机在出现内存溢出异常时Dump出当前的内存堆转储快照以便事后进行分析。
虚拟机栈和本地方法栈溢出导致OOM:
如果线程请求的栈深度大于虚拟机所允许的最大深度,将抛出StackOverflowError异常。
如果虚拟机在扩展栈时无法申请到足够的内存空间,则抛出OutOfMemoryError异常。
栈容量只由-Xss参数设定。
在单个线程下,无论是由于栈帧太大还是虚拟机栈容量太小,当内存无法分配的时候,虚拟机抛出的都是StackOverflowError异常。
在多个线程下,不断的新建线程,申请虚拟机栈和本地方法栈的内存空间,当内存无法分配的时候,虚拟机会抛出OutOfMemoryError异常。
方法区溢出导致OOM:

浙公网安备 33010602011771号