Simpleperf

Simpleperf 是 NDK 软件包中提供的一种多功能命令行工具,方便您为 Android 应用流程执行 CPU 分析。 该工具可帮助您找到使用 Java、C/C++ 和 Kotlin 编写的应用的热点(即,占用您应用大部分执行时间的部分原生代码)。 与热点相关的事件可能指向性能问题,因此,如果您重视应用的性能,应检查并修复热点源。

您可在 Linux、Mac 或 Windows 上运行 Simpleperf。 simpleperf 工具位于 NDK 中的 ndk-location/simpleperf/ 目录下,或者您也可从 AOSP 下载 预构建的抢先体验版工具

要求

要使用 Simpleperf,您必须遵循以下要求:

  • 使用运行 Android 5.0(API 级别 21)或更高版本的设备来分析您的应用。
  • 通过 USB 调试连接,将设备连接至您的开发计算机。
  • 要运行 Python 脚本以进行记录和报告(推荐),需在您的开发计算机上安装以下项目:

    • Python 2.7 或更高版本。
    • 最新版 Android SDK 和 NDK。 您可通过 Android Studio 中的 SDK Manager 安装这些项目。

用法

如需查看最新的用法注释,请参考 Simpleperf README

快速入门

本部分包含使用 Simpleperf 分析 Android 应用的基本说明。

1. 让应用做好接受分析的准备

要分析的应用必须可调试。 在应用清单的 <application> 元素中,确保 android:debuggable 属性设置为 true。 如果您要在 Android Studio 中创建新模块,则系统已为您设置好该属性。

根据您分析的应用是使用 Java 代码或 C++ 代码,您可能还需要执行以下额外步骤:

如果您希望使用 Simpleperf 分析通过 Unity 构建的 Android 应用,请按照这些步骤加入可调试符号。

2. 配置应用分析会话

Simpleperf 提供 Python 脚本 (app_profiler.py) 来简化您运行分析会话的方式。 要配置脚本行为,您可修改 app_profiler.config 文件中的属性,该文件位于您开发计算机上的 ndk-location/simpleperf/ 目录中。

关键属性在下表中列出。

属性名称 说明 示例
app_package_name 要分析的应用软件包名称。 app_package_name="com.example.simpleperf.simpleperfexamplewithnative"
apk_file_path 开发计算机上要分析的应用的可调试 APK 路径。 apk_file_path = "../SimpleperfExampleWithNative/app/build/outputs/apk/app-profiling.apk"
android_studio_project_dir 开发计算机上的 Android Studio 项目路径。 android_studio_project_dir = "../SimpleperfExampleWithNative/"
launch_activity 要分析的应用的主 Activity。 launch_activity = ".GameMainActivity"
recompile_app 使用调试信息将 Dalvik 字节码编译到原生二进制文件中。 如果分析仅使用 Java 的代码,设置为 True。 否则,设置为 False recompile_app = False
record_options 要作为参数传递给设备上运行的 “simpleperf record”命令的分析选项。 record_options = "-g --duration 10"

如果要记录分析会话的调用关系图信息,请参阅记录注意事项,了解如何配置记录选项。

3. 运行应用分析器

要从开发计算机启动分析会话,请从命令行运行 app_profiler.py 脚本。 您可在 ndk-location/simpleperf/ 目录中找到该脚本。

$ python app_profiler.py

该脚本执行以下操作:

  • 根据设备架构,将 Simpleperf 可执行文件的副本推送到 Android 设备(例如,如果目标设备以 ARM64 为基础,则脚本将 ndk-location/simpleperf/bin/android/arm64/simpleperf 可执行文件复制到设备)。
  • 在设备上运行“simpleperf record”命令。 如果成功,该命令将生成带有收集到的配置文件信息的 perf.data 文件。
  • 将已生成的 perf.data 文件副本发回到开发计算机。 默认情况下,该文件将保存到 ndk-location/simpleperf/ 目录。 要更改输出位置,请修改 app_profiler.config 文件中的 perf_data_path 属性。

4. 生成分析报告

您可在文本模式或交互式图形界面中查看分析报告。

  • 文本模式:使用您主机平台的 Simpleperf 可执行文件运行“simpleperf report”命令。 例如,如果您的开发计算机操作系统为 Linux,则使用 ndk-location/simpleperf/bin/linux/x86_64/simpleperf 运行报告命令。
  • 图形模式:从命令行运行 report.py 脚本。 该脚本位于 ndk-location/simpleperf/ 目录中。 该脚本也接受同一参数作为“simpleperf 报告”命令。

Simpleperf 提示与诀窍

如果您刚开始使用 Simpleperf,不妨试试以下一些特别实用的命令。 有关更多命令和选项,请参阅 Simpleperf 命令参考

查找执行时间最长的共享库

您可运行以下命令,查看哪些 .so 文件占用最大比例的执行时间(根据 CPU 周期数)。 启动性能分析会话时,将该命令作为第一个命令运行是不错的选择。

$ simpleperf report --sort dso

查找执行时间最长的函数

当您确定占用最多执行时间的共享库后,您可运行以下命令来查看执行 .so 文件的函数花费的时间百分比。

$ simpleperf report --dsos library.so --sort symbol

查找线程中花费的时间百分比

.so 文件中的执行时间可划分到多个线程中。 您可运行以下命令来查看每个线程中花费的时间百分比。

$ simpleperf report --sort tid,comm

查找对象模块中花费的时间百分比

找到花费最多执行时间的线程后,您可使用以下命令隔离在这些线程上花费最长执行时间的对象模块。

$ simpleperf report --tids threadID --sort dso

了解函数调用的相关性

调用关系图直观地呈现 Simpleperf 在分析会话期间记录的堆栈轨迹。 在开始记录调用关系图信息之前,请参阅记录注意事项

您可使用 report -g 命令打印调用关系图,以查看其他函数调用的函数。 这有利于确定某个函数运行速度缓慢是自身问题,还是由于其调用的一个或多个函数运行缓慢。

$ simpleperf report -g

您也可使用 Python 脚本 report.py -g 来启动显示函数的交互式工具。 您可点击每个函数,以查看其各子组件花费的时间。

记录注意事项

Simpleperf 支持两种在分析会话期间记录调用关系图信息的主要方式,即基于 DWARFrecord --call-graph dwarfrecord -g)和基于堆栈帧指针(record --call-graph fp)。

一般来说,使用 --call-graph fp 进行记录比使用 --call-graph dwarf 快得多。 如果您是针对基于 AArch-64 架构 (arm64-v8a) 构建的设备,而非基于 ARM 架构(armeabiarmeabi-v7a)构建的设备进行分析,则可考虑使用 --call-graph fp 选项。 这是因为在 ARM 架构上构建的设备通常没有堆栈帧寄存器,无法支持使用 --call-graph fp 选项执行可靠的堆栈解退。

相反,如果您是针对基于 ARM 架构构建的设备进行分析,请考虑使用 --call-graph dwarf 选项。 使用 --call-graph dwarf 选项支持 Simpleperf 使用 libunwind 库解退堆栈。 为使用 --call-graph dwarf 选项,您必须在原生库中提供调式信息。 因此,我们建议您构建自己的 APK,以容纳未精简的原生库。

分析使用 Unity 构建的应用

如果您分析的是使用 Unity 构建的应用,请务必依据以下步骤构建包含可调试符号的应用:

  1. 在 Unity Editor 中打开您的 Android 项目。
  2. 在 Android 平台的 Build Settings 窗口中,确保勾选 Development Build 选项。
  3. 点击 Player Settings,将 Stripping Level 属性设置为 Disabled

报告问题

要报告问题或提出功能请求,请使用 GitHub 上的 android-ndk/ndk 问题跟踪器。

另请参阅

  1. Simpleperf 命令参考