JVM 知识--OOM的几种情况

本文最后更新于:5 个月前

    1. 内存溢出 (MemoryOverflow)

      程序中的确需要很多对象,但是没有多余的空间再放入一个新的对象了

    2. 内存泄漏 (Memory Leak)

      大量无用的对象产生导致没有空间了

      使用工具查看泄漏对象到 GC Roots 的引用链,从而定位泄漏代码的位置

    1. 栈扩容时没有办法申请到足够大的空间 (只有允许动态扩展栈容量的虚拟机上才会发生,HotSpot 不可以)
    • HotSpot 只有在多线程下,才会出现 OOM,而在单线程下,实际上是 StackOverFlowError

      常见的 StackOverFlowError 是请求的栈深度大于实际的栈空间大小,并且发生错误会有明确的堆栈打印

      而在多线程下,操作系统 os 分配给每个进程的内存是有限制的.对于 JVM,主要把这个内存分配给堆和栈

      而如果在多线程下,栈越大,所占用的内存越多,越容易发生 OOM

      如果是产生了过多的线程而导致 OOM 的异常的,且不能减少线程数或者更换64位虚拟机的情况下,就只能通过减少最大堆和减少栈容量来换取更多的线程

  • 方法区

    1. 大量类信息,造成内存溢出

    2. 其实还包括运行时常量池的内存溢出

  • 程序计数器是 JVM 唯一没有定义 OOM 的地方

  • 直接内存

    1. 直接或间接用到了直接内存的地方 (间接用到常见的有 NIO)

      一个明显的特征是 Heap Dump 文件中不会看见明显的异常