用于排查内存问题的工具

注意

基本、标准和企业计划将从 2025 年 3 月中旬开始弃用,停用期为 3 年。 建议转换到 Azure 容器应用。 有关详细信息,请参阅 Azure Spring Apps 停用公告

标准消耗和专用计划将于 2024 年 9 月 30 日开始弃用,并在六个月后完全关闭。 建议转换到 Azure 容器应用。

本文介绍可用于排查 Java 内存问题的各种工具。 这些工具用途广泛,不仅限于处理内存问题,不过本文仅重点介绍内存主题。

警报和诊断

以下部分介绍通过 Azure 门户提供的资源运行状况警报和诊断。

资源运行状况

使用 Azure 活动日志和 Azure 服务运行状况,可以监视应用生命周期事件并设置警报。 有关详细信息,请参阅使用 Azure 活动日志和 Azure 服务运行状况监视应用生命周期事件

如果出现容器内存不足 (OOM) 问题,资源运行状况会发送有关应用重启事件的警报。 有关详细信息,请参阅内存不足问题引起的应用重启问题

以下屏幕截图显示了指示 OOM 问题的应用资源运行状况警报。

Azure 门户的屏幕截图,展示的是突出显示 OOM 消息的 Azure Spring Apps 资源运行状况页面。

诊断并解决问题

Azure Spring Apps 诊断是一种无需配置即可对应用进行故障排除的交互式体验。

在 Azure 门户中,可在“诊断和解决问题”下找到“内存使用情况”,如以下屏幕截图所示。

Azure 门户的屏幕截图,展示的是 Azure Spring Apps“诊断和解决问题”页面,其中突出显示了下拉列表中的“内存使用情况”。

“内存使用情况”为应用内存使用情况提供简单的诊断,如以下屏幕截图所示。

Azure 门户的屏幕截图,展示的是 Azure Spring App“内存使用情况”页面。

指标

以下部分介绍了涵盖内存使用率高、堆内存过大、垃圾回收异常(频率过高或过低)等问题的指标。 有关详细信息,请参阅快速入门:使用日志、指标和跟踪监视 Azure Spring Apps 应用

应用内存使用情况

应用内存使用情况是一个由已使用的应用内存除以应用内存限制得出的百分比值。 此值显示完整应用内存。

jvm.memory.used/committed/max

对于 JVM 内存,有三个指标:jvm.memory.usedjvm.memory.committedjvm.memory.max下面的列表描述了这些指标。

“JVM 内存”不是明确定义的概念。 此处,jvm.memory堆内存非堆内存以前的 permGen 部分的总和。 JVM 内存不包括直接内存或其他内存,如线程堆栈。 Spring Boot Actuator 收集这三个指标并确定 jvm.memory 范围。

  • jvm.memory.used 是已使用的 JVM 内存量,包括已使用的堆内存以及非堆内存中以前的 permGen。

    jvm.memory.used 是堆内存更改的主要体现,因为以前的 permGen 部分通常是稳定的。

    如果发现 jvm.memory.used 过大,请考虑设置较小的最大堆内存大小。

  • jvm.memory.committed 是提交以供 JVM 使用的内存量。 jvm.memory.committed 的大小基本为可用 JVM 内存的限制。

  • jvm.memory.max 是 JVM 内存的最大量,请勿与实际可用内存量混淆。

    有时 jvm.memory.max 的值可能会令人混淆,因为它可能远高于可用的应用内存。 为了明确这一点,请明白 jvm.memory.max 是堆内存的全部最大大小和非堆内存以前的 permGen 部分的总和,与实际可用内存无关。 例如,如果在 Azure Spring Apps 门户中设置内存为 1 GB 的应用,则默认堆内存大小将为 0.5 GB。 有关详细信息,请参阅 Java 内存管理中的默认最大堆大小部分。

    如果默认压缩类空间大小为 1 GB,则无论应用内存大小是否为 1 GB,jvm.memory.max 的值都将大于 1.5 GB。 有关详细信息,请参阅 Oracle 文档中的 Java Platform、Standard Edition HotSpot 虚拟机垃圾回收优化指南:其他注意事项

jvm.gc.memory.allocated/promoted

这两个指标用于观察 Java 垃圾回收 (GC) 情况。 有关详细信息,请参阅 Java 内存管理中的 Java 垃圾回收部分。 最大堆大小会影响次要 GC 和完整 GC 的频率。 最大元空间和最大直接内存大小会影响完整 GC。 如果要调整垃圾回收的频率,请考虑修改以下最大内存大小。

  • jvm.gc.memory.allocated 是运行一个 GC 之后,在运行下一个 GC 之前,新代内存池大小增加的量。 此值反映的是次要 GC。

  • jvm.gc.memory.promoted 是运行 GC 之后,旧代内存池大小增加的量。 此值反映的是完整 GC。

可以在Azure 门户上找到此功能,如以下屏幕截图所示。 可以选择特定指标,并针对特定应用、部署或实例添加筛选器。 还可以应用拆分。

Azure 门户的屏幕截图,其中显示了 Azure Spring Apps 的“指标”页。

进一步调试

若要进一步调试,可以手动捕获堆转储和线程转储,并使用 Java Flight Recorder (JFR)。 有关详细信息,请参阅手动捕获堆转储和线程转储并在 Azure Spring Apps 中使用 Java Flight Recorder

堆转储记录 Java 堆内存的状态。 线程转储记录所有实时线程的堆栈。 可通过 Azure CLI 以及 Azure 门户的应用页面使用这些工具,如以下屏幕截图所示。

Azure 门户的屏幕截图,展示的是应用概述页面,其中突出显示了“故障排除”按钮。

有关详细信息,请参阅手动捕获堆转储和线程转储并在 Azure Spring Apps 中使用 Java Flight Recorder。 还可以使用内存分析器等第三方工具分析堆转储。

修改配置以修复问题

你可以识别一些问题,例如容器 OOM、堆内存过大以及垃圾回收异常。 如果识别到以上任一问题,可能需要在 JVM 选项中配置最大内存大小。 有关详细信息,请参阅 Java 内存管理中的重要 JVM 选项部分。

可以使用 Azure 门户或 Azure CLI 修改 JVM 选项。

在 Azure 门户中导航到你的应用,然后从导航菜单的“设置”部分选择“配置”。 在“常规设置”选项卡上更新“JVM 选项”字段,如以下屏幕截图所示:

Azure 门户中应用配置页面的屏幕截图,其中突出显示 JVM 选项。

请参阅