文档首页/ 应用性能管理 APM/ 最佳实践(2.0)/ 使用APM Profiler定位性能问题
更新时间:2026-01-23 GMT+08:00
分享

使用APM Profiler定位性能问题

APM Profiler 是一种持续性能剖析工具,可以帮助开发者准确找到应用程序中消耗资源最多的代码位置。

前提条件

  1. APM Agent 已接入,操作方法参见增强型探针Java语言接入APM
  2. Profiler功能已开启,操作方法参见Profiler性能分析

如何查询并解决CPU升高问题

  1. 登录APM控制台
  2. 单击左侧,选择“管理与监管 > 应用性能管理 APM”,进入APM服务页面。
  3. 在左侧导航栏选择“应用监控 >指标”,进入应用指标页。
  4. 在界面左侧树单击待查看的基础监控环境后的
  5. 单击“基础监控”,切换至基础监控页签,监控项选择“JVM监控”。
  6. 找到“cpu(%)”,发现CPU持续高达80%以上。

    图1 cpu(%)

  7. 单击“Profiler性能分析”,切换至Profiler性能分析页签。
  8. 单击“性能分析”,Profiler性能分析页面,类型选择“CPU Time”。

    图2 Profiler火焰图

  9. 分析火焰图数据,从火焰图中可以看到,java.util.LinkedList.node(int) 方法占用了 66% 的 CPU,而相应的业务代码方法是countPages(List)。

    图3 Profiler火焰图分析

  10. 分析业务代码,结合代码可以发现该方法countPages(List)是对入参集合list进行下标遍历,而通过火焰图运行时数据发现,传入的是LinkedList,而LinkedList底层数据结构是链表,通过下标遍历效率会非常差。

    图4 代码分析

  11. 修复代码,将list的遍历算法从普通的下标for循环改为增强的for循环。

    图5 修复代码

  12. 优化后,重复步骤4~步骤5,发现CPU使用率<1%。

    图6 优化后CPU(%)

如何查询并解决内存升高问题

前提条件:开启测试程序,同时设定heap的大小为2g(-Xms2g -Xmx2g)。

  1. 在左侧导航栏选择“应用监控 > 指标”。
  2. 在界面左侧树单击待查看基础监控环境后的
  3. 单击“基础监控”,切换至基础监控页签,监控项选择“GC监控”。通过GC折线图发现,服务存在频繁的GC问题。

    图7 查看GC监控

  4. 监控项选择“JVM监控”,查看JVM监控。

    图8 查看JVM监控

  5. 单击“Profiler性能分析”,切换至Profiler性能分析页签。
  6. 单击“性能分析”,Profiler性能分析页面,实例选择“Allocated Memory”。根据右侧Self排序排查,找到分配内存最多的方法。

    图9 内存火焰图

  7. 查看代码,发现LargeEnum是个枚举类,定义了大量的常量。由于枚举类的方法values()底层是通过数组clone实现的,即每次调用values()方法,底层会复制一个枚举数组,所以会导致频繁分配堆内存,频繁GC。

    图10 查看代码

  8. 问题修复,将values定义为一个常量,避免频繁调用enum.values()。

    图11 问题修复

  9. 重复步骤3~步骤6,发现GC次数大幅下降,并且火焰图中找不到enum.values()内存分配。

    图12 优化后GC监控
    图13 优化后性能分析火焰图

如何查询并解决接口响应慢问题

  1. 在左侧导航栏选择“应用监控 > 指标”。
  2. 在界面左侧树单击待查看基础监控环境后的
  3. 单击“接口调用”,切换至接口调用页签。通过APM的接口调用功能发现接口响应慢,平均响应时间80s左右。

    图14 接口调用

  4. 单击“Profiler性能分析”,切换至Profiler性能分析页签。
  5. 单击“性能分析”,Profiler性能分析页面,实例选择“Latency”, 输入接口所在的方法。

    图15 性能分析

  6. 排查调用栈,寻找耗时的方法。如下图,NegativeWorkService#handle中executeUpdate()方法耗时最多。

    图16 排查调用栈

  7. 排查NegativeWorkService#handle方法,发现根因是循环内执行数据库插入操作。

    图17 排查NegativeWorkService#handle方法

  8. 问题修复,改为批量插入数据。

    图18 问题修复

  9. 观察接口调用平均响应时间,从80s减少到0.2s。

    图19 优化后查询接口调用平均响应时间

相关文档