更新时间:2025-08-19 GMT+08:00
分享

通过Profiler分析代码性能

Profiler性能分析,自动获取应用程序运行过程中的CPU、内存的使用情况,通过火焰图的实时展示每一个方法的调用关系和执行率,帮助优化代码性能。

使用限制

  • Alpine Linux系统不支持Profiler功能。因为Alpine Linux是一个轻量级的Linux系统发行版,缺少运行Profiler的必要依赖。如果需要支持Profiler功能,建议使用标准Linux操作系统。
  • 为了应用运行稳定,强烈建议您按照要求升级JDK版本,在低版本的JDK上使用Profiler性能分析功能,存在应用崩溃的风险。
    表1 JDK版本说明

    JDK类型

    版本

    OpenJDK

    • OpenJDK 8u352+
    • OpenJDK 17.0.5+

    Oracle JDK

    • Oracle JDK 17.0.9+
  • 支持Profiler性能分析功能的Agent版本详情,请参考JavaAgent更新说明
  • Agent获取地址,请参考探针下载地址
  • 其它使用限制,请参见下表。
    表2 使用限制以及说明

    序号

    使用限制及说明

    1

    Profiler功能当前受限使用,且每个环境最多支持开启500个Profiler。

    2

    Profiler引导页,仅在首次开启Profiler功能时展示。

    3

    Profiler仅支持JAVA。

    4

    如果-XX:MaxJavaStackTraceDepth为零或负,则不会收集任何Java堆栈。

    5

    • CPU Profiler依赖perf_event_open的系统调用,但因为Linux kernel的Syscall安全策略(seccomp)控制,可能会禁止进程调用特定Syscall。
    • Docker环境:执行以下命令运行容器。如需配置更精细化的系统调用控制,请参见https://docs.docker.com/engine/security/seccomp/。
     docker run --security-opt seccomp=unconfined  XXX  
    • Kubernetes环境:配置特权容器参数privileged: true,特权容器始终保持为Unconfined。

    如需配置更精细化的系统调用控制,请参见https://kubernetes.io/zh-cn/docs/tutorials/security/seccomp/。

    6

    Profiler为目标进程的每个线程分配8kB perf_event缓冲区,Linux内核中限制了进程perf_event相关的MMap的总内存大小, 在非特权用户下运行时,确保/proc/sys/kernel/perf_event_mlock_kb值足够大(超过8*线程数): echo 8*threads+ 4 > /proc/sys/kernel/perf_event_mlock_kb 。

性能影响

CPU&内存诊断功能经性能测试,在一般的Spring Web应用所有功能效果全部开启的情况下, CPU增加开销5%左右,堆外增加内存开销50 M左右,GC以及请求延迟增加不明显。

通过Profiler分析代码性能

Profiler性能分析支持如下功能:

  • 开启性能分析Profiler:首次使用Profiler性能分析功能时,需要开启Profiler。
  • 分析代码性能:Profiler性能分析会自动获取应用程序运行过程中CPU和内存和时延的使用情况。通过火焰图实时展示每一个方法、类和线程的调用关系和执行效率,帮助您优化代码性能。
  • 对代码性能差异:通过火焰图实时展示两个实例或同一个实例不同时间段的方法、类和线程的调用关系和执行效率的差异,帮助您对比代码性能差异。
  • 查看代码性能快照:支持快照列表查询功能。快照列表以分钟为时间维度,获取应用程序的调试信息,如CPU核数、内存分配速率、实例名称以及主机名称。
  • 查看建议:支持查看建议。Profiler根据用户的性能数据,识别出超过CPU使用率阈值的方法,然后给出合理的建议。

操作步骤

  1. 登录APM控制台
  2. 单击左侧,选择“管理与监管> 应用性能管理 APM”,进入APM服务页面。
  3. 在左侧导航栏选择“性能监控 >组件列表”,进入组件列表页面。
  4. 在左侧“快速筛选”栏中,选择“区域”、“应用”以及“技术栈”。
  5. 单击“组件”列,某一个组件名称,进入该组件指标项详情页。
  6. 单击“Profiler性能分析”,切换至Profiler性能分析页签。
  7. 首次进入“Profiler性能分析”页签时,单击“开启Profiler”开启Profiler性能分析功能。

    图1 Profiler性能分析
    • 仅2.4.5-profiler版本及以后版本的Agent,支持Profiler性能分析功能。
    • 如需关闭Profiler性能分析功能,可在“组件设置”中关闭Profiler性能分析功能。详情请参考设置组件监控开关

  8. 开启Profiler后,您可以根据需要执行如下操作:

    • 性能分析
      单击“Profiler性能分析”页签下的“性能分析”子页签,进入“性能分析”页面,执行如下操作:
      1. 在“性能分析”页面选择您想要查看的实例,设置性能分析类型、范围、以及聚合维度查询条件,即可以查看该实例对应的性能分析数据。
        图2 性能分析
        表3 查询参数说明

        选择项

        参数

        说明

        类型

        CPU Time

        每个方法在CPU上的运行时间。

        Allocated Memory

        已分配的堆内存(包括已被回收和未被回收的部分),使用场景包括频繁GC(Garbage Collection)等。

        Live Object Memory

        已分配但未被回收的堆内存,使用场景主要包括内存泄漏等。该功能需要JDK版本为JDK17。

        Latency

        Trace相关线程的代码方法执行的总耗时。包括方法在CPU上的运行时间、等待I/O的时间、以及方法运行时发生的任何其他时间。

        范围

        My Code

        查询用户代码。

        All Code

        查询全部代码。

        聚合维度

        Line

        以代码行维度进行聚合。

        Method

        以方法维度进行聚合。

        Class

        以类维度进行聚合。

        Package

        以Java包名称维度进行聚合。

        表4 性能分析参数说明

        参数

        说明

        火焰图

        • 火焰图Y轴(纵轴)表示调用栈,每一层都是一个函数(包),调用的越深,火焰层数越高,最底部(火焰尖)是正在执行的函数,上方是他的父函数。
        • 火焰图X轴(横轴)表示CPU占用时长、trace相关线程的方法执行的总耗时、已分配的堆内存大小或者已分配但未被回收的堆内存大小。以CPU占用时长为例,占用的CPU时间越长,在火焰图X轴上的距离越长。
        • 在火焰图中,相同的方法或包显示的颜色相同。
        • 鼠标放在火焰图上,展示某一个方法、类和线程的详细信息。
        • 单击火焰图中某个方法条,该方法条横向放大。单击首列“Total”列标题行,火焰图还原。

        方法路径

        • 鼠标放在Location类某个方法名称上,展示该方法的详细信息。
        • 单击Location类某个方法名称,火焰图侧对应的方法会高亮显示,其余方法灰化。再次单击同一个方法名称,火焰图恢复原状。

        Self

        仅方法自身的性能消耗,不包含调用方法。该数值为所有线程执行结果的总和,因此结果有可能大于所选时间段。

        Total

        总性能消耗,包含方法自身及其调用方法。该数值为所有线程执行结果的总和,因此结果有可能大于所选时间段。

      2. 您还可以根据需要执行以下操作:
        • 按照方法路径搜索:搜索框设置搜索条件后,单击,查看满足搜索条件的火焰图。
        • 单击时间维度选择按钮,默认“近20分钟”。

          当前支持“近5分钟”、“近20分钟”、“近1小时”、“近3小时”、“近6小时”、“近1天”、“今天”、“昨天”以及自定义。

        • 页面下方实时展示每一个线程、方法、类和包的调用关系和执行效率。
    • 对比
      单击“Profiler性能分析”页签下的“对比”子页签,进入“对比”页面,执行如下操作:
      1. 在“对比”页面设置您想要对比的实例对象(包括实例和时间段)、性能分析类型、范围以及聚合维度,比对类型、即可以查看实例对比的性能分析数据。
        图3 代码性能对比
        • 对比实例对象:分别支持选择相同或不同时间段的不同实例,或选择不同时间段的相同实例。
        • 选择实例:在下拉列表中选择实例,当前支持选择1个实例。
        • 性能分析类型、范围、以及聚合维度设置请参考表3
        • 比对类型:当前支持table、flame两种类型。
          表5 比对类型参数说明

          参数

          说明

          flame

          以火焰图类型进行对比:

          • 火焰图Y轴(纵轴):表示调用栈。每一层都是一个函数(包),调用的越深,火焰层数越高。最底部(火焰尖)是正在执行的函数,上方是他的父函数。
          • 火焰图X轴(横轴):表示占用时间(内存视图表示占用内存)长度。占用的CPU时间越长,其宽度越宽。
          • 鼠标放在火焰图上,可展示某一个方法、类和线程的详细信息。
          • 单击火焰图中某个方法条,该方法条可横向放大。单击“Total”列标题行,火焰图还原。
          • 火焰图颜色:红色表示当前实例对比值较大;绿色表示当前实例对比值较小;蓝色表示该方法、类或线程,仅在当前实例侧存在;白色表示当前实例对比值相同。

          table

          以表格类型进行对比:

          • 展示方法路径、Baseline(基线总性能耗时)、Comparison(对比总性能耗时)、以及Diff(耗时差时)数据。
          • 鼠标放任意一行对比结果上,可展示该方法的对比详细信息。
      2. 您还可以根据需要执行以下操作:
        • 单击时间维度选择按钮,默认“近20分钟”。

          当前支持“近5分钟”、“近20分钟”、“近1小时”、“近3小时”、“近6小时”、“近1天”、“今天”、“昨天”以及自定义。

        • 按照方法路径搜索:搜索框设置搜索条件后,单击,查看满足搜索条件的火焰图。
        • 查看每一个方法、类和线程的调用关系和执行效率的实时数据。
    • 快照列表
      • 单击“Profiler性能分析”页签下的“快照列表”子页签,进入“快照列表”页面,执行如下操作:
        1. 选择您想要查看的实例,可以查看该实例对应的快照数据。
          图4 查看快照列表
          表6 快照列表参数说明

          参数

          说明

          日期

          获取调试信息的时间。

          CPU核数

          CPU利用率。

          内存分配速率

          内存的速度,代表该内存所能达到的最高工作频率。

          实例名称

          实例名称。

        2. 单击时间维度选择按钮,默认“近20分钟”。

          当前支持“近5分钟”、“近20分钟”、“近1小时”、“近3小时”、“近6小时”、“近1天”、“今天”、“昨天”以及自定义。

    • 建议
      • 单击“Profiler性能分析”页签下的“建议”子页签,进入“建议”页面,执行如下操作:
        1. 单击时间维度选择按钮,默认“近20分钟”。
          当前支持“近5分钟”、“近20分钟”、“近1小时”、“近3小时”、“近6小时”、“近1天”、“今天”、“昨天”以及自定义。
          图5 查看建议
          表7 建议参数说明

          参数

          说明

          类型

          性能问题类型,目前只有cpu类型,后期内存,时延类型会依次上线。

          性能问题

          具体的性能问题的描述。

          调用方法

          当前问题出现的方法名。

          问题出现数

          在查询的时间范围内,当前性能问题出现的次数。

          CPU使用率

          当前问题最后一次出现,所使用的资源(cpu)的使用率。

          操作

          支持的其他操作类型,目前仅支持查看详情

        2. 单击操作列的“查看详情”,展示某个问题的建议。包括:开始时间、结束时间、问题描述、当前状态、建议修改步骤、问题详情,并支持按照方法路径搜索。
          图6 建议详情

常见问题

在Profiler性能分析的火焰图无数据或其他异常情况下,可以查看Profiler日志确定问题原因。详细操作参见Profiler性能分析常见问题

了解“Profiler性能分析”的更多内容,请参见Profiler性能分析

相关文档