内存不足问题导致的应用重启问题

注意

Azure Spring Apps 是 Azure Spring Cloud 服务的新名称。 虽然该服务有新名称,但一些地方仍会使用旧名称,我们仍在更新屏幕截图、视频和图形等资产。

本文介绍 Azure Spring Apps 中 Java 应用程序的内存不足 (OOM) 问题。

内存不足问题的类型

存在两种类型的内存不足问题:容器 OOM 和 JVM OOM。

  • 可用应用内存用完时会发生容器 OOM(也称为“系统 OOM”)。容器 OOM 问题会导致应用重启事件,这些事件在 Azure 门户的“资源运行状况”部分中报告。 通常,容器 OOM 是由内存大小配置不正确造成的。

  • 当已用内存达到 JVM 选项中设置的最大大小时,就会发生 JVM OOM。 JVM OOM 不会导致应用重启。 通常,JVM OOM 是错误代码的结果,可以通过在应用程序日志中查找 java.lang.OutOfMemoryError 异常来明确。 JVM OOM 对应用程序和 Java 分析工具(例如 Java 网络流量记录器)有负面影响。

本文重点介绍如何解决容器 OOM 问题。 若要解决 JVM OOM 问题,请检查堆转储、线程转储和 Java 网络流量记录器等工具。 有关详细信息,请参阅手动捕获堆转储和线程转储并在 Azure Spring Apps 中使用 Java 网络流量记录器

解决 OOM 导致的应用重启问题

以下部分介绍了可用于诊断和解决容器 OOM 问题的工具、指标和 JVM 选项。

在“资源运行状况”页面上查看警报

Azure 门户上的“资源运行状况”页面显示了容器 OOM 导致的应用重启事件,如以下屏幕截图所示:

Screenshot of Azure portal showing Azure Spring Apps Resource Health page with OOM message highlighted.

配置内存大小

应用内存量、jvm.memory.usedjvm.memory.committed 指标提供了内存量的视图。 有关详细信息,请参阅用于排查内存问题的工具指标部分。 在 JVM 选项中配置最大内存大小,从而确保内存处于限制范围内。

Java 内存模型中所有部件的最大内存大小总和应小于实际可用的应用内存。 若要设置最大内存大小,请参阅 Java 内存管理内存使用量布局部分中介绍的典型内存布局。

请在设置最大内存大小时找到平衡点。 将最大内存大小设置得过高时,就会有容器 OOM 的风险。 将最大内存大小设置得过低时,就会有 JVM OOM 的风险,并且垃圾回收将导致应用运行变慢。

控制堆内存

可以使用 -Xms-Xmx-XX:InitialRAMPercentage-XX:MaxRAMPercentage JVM 选项设置最大堆大小。

当指标中 jvm.memory.used 的值过高时,可能需要调整最大堆大小设置。 有关详细信息,请参阅用于排查内存问题的工具jvm.memory.used/committed/max 部分。

控制直接内存

出于以下原因,设置 -XX:MaxDirectMemorySize JVM 选项至关重要:

  • 当 nio 和 gzip 等框架使用直接内存时,可能不会注意到。
  • 直接内存的垃圾回收仅在完全垃圾回收期间处理,并且仅在堆接近满时才发生完全垃圾回收。

通常,可以将 MaxDirectMemorySize 设置为某个值,该值小于应用内存大小减去堆内存减去非堆内存的值。

控制元空间

可以通过设置 -XX:MaxMetaspaceSize JVM 选项来设置最大元空间大小。 -XX:MetaspaceSize 选项设置阈值来触发完全垃圾回收。

元空间内存通常是稳定的。

请参阅