知识库

内存不足错误后的恢复建议

可以配置 JVM (Java 虚拟机), 使其在遇到 OOM (内存不足) 错误时强制抛出异常并崩溃或仅关闭应用程序。在第一次出现 OOM 时采取行动可以帮助避免因内存不足情况而导致的更多受害者, 这些受害者可能会根据其当时的内存需求遇到 OOM, 还可以减少恢复时间。此外, 这实际上可能允许因 OOM 而失败的操作在应用程序重启后成功完成, 并重试这些操作, 因为内存占用量已发生变化。如果诊断问题是优先事项, 则选择 CrashOnOutOfMemoryError 而不是 ExitOnOutOfMemoryError 更好。

CrashOnOutOfMemoryError

如果启用此选项, 当发生内存不足错误时, JVM 将崩溃并生成文本和二进制崩溃文件 (如果启用了核心文件)。

格式
-XX:+|-CrashOnOutOfMemoryError
示例
java -XX:+CrashOnOutOfMemoryError
Neo4j 配置文件 (neo4j.conf) 条目
dbms.jvm.additional=-XX:+CrashOnOutOfMemoryError

ExitOnOutOfMemoryError

启用此选项后, JVM 在首次出现内存不足错误时退出。如果您希望重新启动 JVM 实例而不是处理内存不足错误, 可以使用它。

格式
-XX:+|-ExitOnOutOfMemoryError
Neo4j 配置文件 (neo4j.conf) 条目
dbms.jvm.additional=-XX:+ExitOnOutOfMemoryError

-XX:+ExitOnOutOfMemoryError 优先于 -XX:+CrashOnOutOfMemoryError

ExitOnOutOfMemoryErrorCrashOnOutOfMemoryError 标志已添加到 Java SE 8 Update 92。有关更多信息, 请参阅 8u92 更新发行说明 中的“新 JVM 选项”部分。

JDK-8155004 : CrashOnOutOfMemoryError 无法处理由于无法创建线程而导致的 OOM

存在多种类型的 OutOfMemoryError

  • java.lang.OutOfMemoryError: Java 堆空间

当应用程序尝试向堆空间区域添加更多数据, 但没有足够的空间时, 将触发此错误。请注意, 可能存在大量的物理内存可用, 但只要 JVM 达到堆大小限制, 就会抛出 java.lang.OutOfMemoryError: Java 堆空间 错误。

  • java.lang.OutOfMemoryError: GC 占用时间过长

此错误表示 GC 尝试释放内存, 但几乎无法完成任何工作。默认情况下, 当 JVM 在 GC 中花费超过 98% 的总时间并且在 GC 后回收的堆少于 2% 时, 会发生这种情况。

  • java.lang.OutOfMemoryError: 元空间/压缩类空间

导致此错误的主要原因是, 太多类或太大类被加载到元空间。

  • java.lang.OutOfMemoryError: 无法创建新本地线程

每当底层操作系统无法分配新本地线程时, 都会抛出此 OutOfMemoryError。本地线程的确切限制取决于平台。

  • java.lang.OutOfMemoryError: 交换空间不足?

当 JVM 从本地堆分配字节的请求失败并且本地堆接近耗尽时, 会抛出此错误。它通常是由操作系统级问题引起的, 例如

  • 操作系统配置的交换空间不足。

  • 系统上的另一个进程正在消耗所有内存资源。

    • java.lang.OutOfMemoryError: 请求的数组大小超出 VM 限制

这意味着发生崩溃的应用程序正在尝试分配一个比 Java 虚拟机支持的更大的数组。