
# 通过Profiler分析代码性能
Profiler性能分析，自动获取应用程序运行过程中的CPU、内存的使用情况，通过火焰图的实时展示每一个方法的调用关系和执行率，帮助优化代码性能。
#### 使用限制
- Alpine Linux系统不支持Profiler功能。因为Alpine Linux是一个轻量级的Linux系统发行版，缺少运行Profiler的必要依赖。如果需要支持Profiler功能，建议使用标准Linux操作系统。
- 为了应用运行稳定，强烈建议您按照要求升级JDK版本，在低版本的JDK上使用Profiler性能分析功能，存在应用崩溃的风险。
  表1JDK版本说明 
  | JDK类型      | 版本                                                                                                                                                                                                  |
  |:---|:---|
  | OpenJDK    | - OpenJDK 8u352+  - OpenJDK 17.0.5+   |
  | Oracle JDK | - Oracle JDK 17.0.9+                                                                                     |
     
  
- 支持Profiler性能分析功能的Agent版本详情，请参考[JavaAgent更新说明](https://support.huaweicloud.com/productdesc-apm2/apm_01_0093.html)。
- Agent获取地址，请参考[探针下载地址](https://support.huaweicloud.com/usermanual-apm2/apm_07_1007.html)。
- 其它使用限制，请参见下表。
  表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控制台](https://auth.huaweicloud.com/authui/login.html?service=https://console.huaweicloud.com/console/#/login)。
2. 单击左侧![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002549695587.png)，选择"管理与监管\> 应用性能管理 APM"，进入APM服务页面。
3. 在左侧导航栏选择"性能监控 \>组件列表"，进入组件列表页面。
4. 在左侧筛选栏中，选择"区域"以及"所属应用"。
5. 单击"组件"列，某一个组件名称，进入该组件指标项详情页。
6. 单击"Profiler性能分析"，切换至Profiler性能分析页签。
7. 首次进入"Profiler性能分析"页签时，单击"开启Profiler"开启Profiler性能分析功能。
   
   图1Profiler性能分析   
   ![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002549695601.png "点击放大")
   - 仅2.4.5-profiler版本及以后版本的Agent，支持Profiler性能分析功能。
   
   - 如需关闭Profiler性能分析功能，可在"组件设置"中关闭Profiler性能分析功能。详情请参考[设置组件监控开关](https://support.huaweicloud.com/usermanual-apm2/apm_07_0223.html#apm_07_0223__section1639518455154)。
    
   
   
8. 开启Profiler后，您可以根据需要执行如下操作： 
   - 性能分析
     单击"Profiler性能分析"页签下的"性能分析"子页签，进入"性能分析"页面，执行如下操作：
     1. 在"性能分析"页面选择您想要查看的实例，设置性能分析类型、范围、以及聚合维度查询条件，即可以查看该实例对应的性能分析数据。
        图2性能分析   
        ![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002518335744.png "点击放大")
         表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. 您还可以根据需要执行以下操作：
        - 按照方法路径搜索：搜索框设置搜索条件后，单击![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002518175840.png)，查看满足搜索条件的火焰图。
        
        - 单击时间维度选择按钮，默认"近20分钟"。 当前支持"近5分钟"、"近20分钟"、"近1小时"、"近3小时"、"近6小时"、"近1天"、"今天"、"昨天"以及自定义。
          
        
        - 页面下方实时展示每一个线程、方法、类和包的调用关系和执行效率。
         
       
   
   - 对比
     单击"Profiler性能分析"页签下的"对比"子页签，进入"对比"页面，执行如下操作：
     1. 在"对比"页面设置您想要对比的实例对象（包括实例和时间段）、性能分析类型、范围以及聚合维度，比对类型、即可以查看实例对比的性能分析数据。
        图3代码性能对比   
        ![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002518335750.png "点击放大")
        - 对比实例对象：![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002518335760.png)和![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002549695589.png)分别支持选择相同或不同时间段的不同实例，或选择不同时间段的相同实例。
        
        - 选择实例：在下拉列表中选择实例，当前支持选择1个实例。
        
        - 性能分析类型、范围、以及聚合维度设置请参考[表3]。
        
        - 比对类型：当前支持table、flame两种类型。
          表5比对类型参数说明 
          | 参数    | 说明                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
          |:---|:---|
          | flame | 以火焰图类型进行对比： - 火焰图Y轴（纵轴）：表示调用栈。每一层都是一个函数（包），调用的越深，火焰层数越高。最底部（火焰尖）是正在执行的函数，上方是它的父函数。  - 火焰图X轴（横轴）：表示占用时间（内存视图表示占用内存）长度。占用的CPU时间越长，其宽度越宽。  - 鼠标放在火焰图上，可展示某一个方法、类和线程的详细信息。  - 单击火焰图中某个方法条，该方法条可横向放大。单击"Total"列标题行，火焰图还原。    - 火焰图颜色：红色表示当前实例对比值较大；绿色表示当前实例对比值较小；蓝色表示该方法、类或线程，仅在当前实例侧存在；白色表示当前实例对比值相同。   |
          | table | 以表格类型进行对比： - 展示方法路径、Baseline（基线总性能耗时）、Comparison（对比总性能耗时）、以及Diff（耗时差时）数据。  - 鼠标放任意一行对比结果上，可展示该方法的对比详细信息。                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
             
          
         
     
     2. 您还可以根据需要执行以下操作：
        - 单击时间维度选择按钮，默认"近20分钟"。 当前支持"近5分钟"、"近20分钟"、"近1小时"、"近3小时"、"近6小时"、"近1天"、"今天"、"昨天"以及自定义。
          
        
        - 按照方法路径搜索：搜索框设置搜索条件后，单击![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002549695605.png)，查看满足搜索条件的火焰图。
        
        - 查看每一个方法、类和线程的调用关系和执行效率的实时数据。
         
       
   
   - 快照列表
     - 单击"Profiler性能分析"页签下的"快照列表"子页签，进入"快照列表"页面，执行如下操作：
       1. 选择您想要查看的实例，可以查看该实例对应的快照数据。
          图4查看快照列表   
          ![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002518335758.png "点击放大")
          表6快照列表参数说明 
          | 参数     | 说明                      |
          |:---|:---|
          | 日期     | 获取调试信息的时间。              |
          | CPU核数  | CPU利用率。                 |
          | 内存分配速率 | 内存的速度，代表该内存所能达到的最高工作频率。 |
          | 实例名称   | 实例名称。                   |
             
          
       
       2. 单击时间维度选择按钮，默认"近20分钟"。 当前支持"近5分钟"、"近20分钟"、"近1小时"、"近3小时"、"近6小时"、"近1天"、"今天"、"昨天"以及自定义。
          
        
      
   
   - 建议
     - 单击"Profiler性能分析"页签下的"建议"子页签，进入"建议"页面，执行如下操作：
       1. 单击时间维度选择按钮，默认"近20分钟"。
          当前支持"近5分钟"、"近20分钟"、"近1小时"、"近3小时"、"近6小时"、"近1天"、"今天"、"昨天"以及自定义。
          图5查看建议   
          ![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002518335746.png "点击放大")
          表7建议参数说明 
          | 参数     | 说明                                                    |
          |:---|:---|
          | 类型     | 性能问题类型，目前只有cpu类型，后期内存，时延类型会依次上线。                      |
          | 性能问题   | 具体的性能问题的描述。                                           |
          | 调用方法   | 当前问题出现的方法名。                                           |
          | 问题出现数  | 在查询的时间范围内，当前性能问题出现的次数。                                |
          | CPU使用率 | 当前问题最后一次出现，所使用的资源（cpu）的使用率。                           |
          | 操作     | 支持的其他操作类型，目前仅支持[查看详情]。 |
             
          
       
       2. 单击操作列的"查看详情"，展示某个问题的建议。包括：开始时间、结束时间、问题描述、当前状态、建议修改步骤、问题详情，并支持按照方法路径搜索。
          图6建议详情   
          ![](https://support.huaweicloud.com/usermanual-apm2/zh-cn_image_0000002549695591.png "点击放大") 
        
      
   
   
   
   
 
#### 常见问题
在Profiler性能分析的火焰图无数据或其他异常情况下，可以查看Profiler日志确定问题原因。详细操作参见[Profiler性能分析常见问题](https://support.huaweicloud.com/apm2_faq/apm_faq_0009.html)。
了解"Profiler性能分析"的更多内容，请参见[通过Profiler分析代码性能](https://support.huaweicloud.com/usermanual-apm2/apm_07_1027.html)。
