使用内存热点诊断堆内存使用高的问题

ARMS内存热点作为一种监控诊断工具,通过持续剖析技术记录线程每个触发堆内存分配阈值时的内存分配大小/次数,以及触发时刻的方法栈快照,定位JVM堆内存使用率高的根因。当系统JVM堆内存利用率高时,ARMS内存热点可为您快速定位到导致堆内存申请量/申请次数高的相关业务逻辑方法栈。

开启内存热点

  1. 登录ARMS控制台,在左侧导航栏选择应用监控 > 应用列表

  2. 应用列表页面顶部选择目标地域,然后单击目标应用名称。

    说明

    语言列显示Java图标图标的应用为接入应用监控的应用,显示-图标的应用为接入可观测链路 OpenTelemetry 版的应用。

  3. 在左侧导航栏中单击应用设置,然后单击自定义配置页签。

  4. 持续剖析区域开启总开关,然后开启内存热点开关,配置需要开启的应用实例的IP地址或者一组实例所属的网段地址。

  5. 在页面底部单击保存

    无需重启应用即可生效。

通过持续剖析查看内存热点数据

示例:一个每秒申请1 MB堆内存的方法。

public class FixedRateAllocAction {

    //请求入口方法
   public void runBusiness() {
        try {
            sink = new byte[1024];
        } catch (InterruptedException e) {
            // Ignore
        }
    }
}
  1. 登录ARMS控制台,在左侧导航栏选择应用监控 > 应用列表

  2. 应用列表页面顶部选择目标地域,然后单击目标应用名称。

    说明

    语言列显示Java图标图标的应用为接入应用监控的应用,显示-图标的应用为接入可观测链路 OpenTelemetry 版的应用。

  3. 在左侧导航栏单击持续剖析,在左侧实例列表中选择目标实例,然后在右侧页面设置数据展示时间。

  4. 在右侧查询页签,您可以筛选数据并查看聚合分析。

    image

  5. 单击聚合分析,在新页面中选择性能分析类型Allocated Memory

    说明

    性能分析类型:

    • CPU Time:CPU申请量热点剖析数据。更多信息,请参见使用CPU热点诊断CPU消耗高的问题

    • Allocated Memory:内存申请量热点剖析数据。

    • Allocations:内存申请次数热点剖析数据,可以查看哪些方法申请内存次数频繁。

    image

    图中左侧为本次调用中涉及的所有方法堆内存申请量情况列表,右侧为对应方法所有方法栈信息绘制的火焰图。其中:

    • Self列表示方法在自身的调用栈中所消耗的时间或资源,不包括其子方法调用所消耗的时间或资源。可以用于识别哪些方法在自身内部花费了大量的时间或资源。

    • Total列包含方法自身消耗的时间或资源,及其所有子方法调用所消耗的时间或资源。可以帮助了解整个方法调用栈中哪些方法贡献了最多的时间或资源。

    根据上图,进行如下分析:

    1. Self值从大到小排列,找到并单击Self值最大的方法com.alibaba.cloud.pressure.memory.FixedRateAllocAction.runBusiness(),右侧火焰图中将会聚焦相关方法。

      image

    2. 聚焦后可以发现,com.alibaba.cloud.pressure.memory.FixedRateAllocAction.runBusiness()就是右侧火焰图中的最宽栈顶方法。

    3. 由于该较宽栈顶即为所分析应用自身定义的方法行,因此,com.alibaba.cloud.pressure.memory.FixedRateAllocAction.runBusiness()方法是该火焰图所采集时段内资源占用较大的显著瓶颈所在,可以根据相关方法名,对业务中相关方法的逻辑进行梳理,查看是否存在优化空间。

通过上述分析,可以看到在1分钟内,com.alibaba.cloud.pressure.memory.FixedRateAllocAction.runBusiness()方法申请了56.56 MB堆内存,与示例场景逻辑基本吻合。