本文翻译自https://developer.android.com/ndk/guides/simpleperf.html
Simpleperf是一个强大的命令行工具,它包含在NDK中,可以帮助我们分析应用的CPU性能。Simpleperf可以帮助我们找到应用的热点,而热点往往与性能问题相关,这样我们就可以分析修复热点源。
各个平台的NDK工具均支持Simpleperf,NDK的版本应不低于r13b,我们可以在
ndk-location/simpleperf/
目录下找到它或者从AOSP的prebuilt中下载。
环境要求
为了使用Simpleperf, 需要以下环境:
- 待分析的App应运行在Android 5.0或者更高版本的设备上
- 使能手机的USB debugging连接到宿主机器
- 为了能够运行Python scripts,宿主机器应安装:
- Python 2.7或者更高版本
- 最新版本的Android SDK以及NDK
使用方法
最新的使用方法请参考Simpleperf README
快速入门
该部分讲述使用Simpleperf分析Android App的基本步骤。
- 准备需要分析的App
待分析的App必须是debuggable,在App manifest application标签中确保android:debuggable
为true.
取决于要分析App的Java层还是Native层,可能需要下面额外的步骤:
- 如果分析运行在Android O上的App的Java层,必须在Apk中添加wrap.sh,细节参考sample Gradle build script for Java code
- 如果分析包含C++代码或者预编译的native库的App:
- 避免使用
-O0
选项, 因为它可能导致C++代码运行缓慢,而应该使用release build type,请参考sample Gradle build script for native code - 尽可能的使用带有调试信息的native库,如何使用带有调试信息的库构建APK请参考sample Gradle build script for native code
- 避免使用
- 配置app profiling脚本
Simpleperf提供了一个Python脚本(app_profiler.py)可以让我们方便的运行分析工具,另外,我们可以通过修改ndk-location/simpleperf/
目录下的app_profiler.config文件中的属性来配置脚本。
下面的表格列出了关键属性。
属性名 | 描述 | 例子 |
---|---|---|
app_package_name | 待分析的App的package name | app_package_name="com.example.simpleperf.simpleperfexamplewithnative" |
apk_file_path | 待分析的App的APK路径 | apk_file_path = "../SimpleperfExampleWithNative/app/build/outputs/apk/app-profiling.apk" |
android_studio_project_dir | Android Strudio工程路径 | android_studio_project_dir = "../SimpleperfExampleWithNative/" |
launch_activity | 待分析的App的Main Activity | launch_activity = ".GameMainActivity" |
recompile_app | 将字节码编译成带有调试信息的机器码,如果只分析java代码设置为True,否则False | recompile_app = False |
record_options | 分析选项,以参数的形式传递给Simple record命令 | record_options = "-g --duration 10" |
如果想要记录方法调用图信息,请参考注意事项
- 运行app profiler脚本
在你的开发机器上从命令行中运行app_profiler.py脚本(在ndk-location/simpleperf/
目录下)就开始分析任务了。
$ python app_profiler.py
该脚本执行以下操作:
- 基于Android设备的体系架构,拷贝相应的Simpleper可执行文件到设备中
- 在Android设备上运行
simpleper record
命令,如果执行成功将生成perf.data文件(存放收集的信息) - 将perf.data文件从Android设备拷贝到开发机器上,默认存放在
ndk-location/simpleperf/
目录下
- 生成分析报告
我们可以通过文本模式或者图形用户界面查看分析报告。
- 文本模式:使用你的宿主开发机器上的simple可执行文件运行
simpleperf reprot
命令,如果你的开发机器是linux(64位),则使用ndk-location/simpleperf/bin/linux/x86_64/simpleperf
- 图形用户界面:运行
ndk-location/simpleperf/
目录下的reprot.py脚本 - 火焰图:参考
ndk-location/simpleperf/doc/README.md
(最新NDK)
Simpleperf小技巧
如果你刚开始使用Simpleperf,下面列出了一些对查找特定内容比较有用的命令,更多命令请参考Simpleperf Command Reference
- 查找最耗时的共享库
使用该命令可以查看最耗时的共享库文件
$ simpleperf report --sort dso
- 查找最耗时的函数
当你找到了最耗时的共享库,再使用该命令可以找到共享库中最耗时的函数
$ simpleperf report --dsos library.so --sort symbol
- 查看线程耗时百分比
$ simpleperf report --sort tid,comm
- 查找线程执行最耗时的目标模块(共享库)
在找到了最耗时的线程之后,使用该命令可以查找线程中最耗时的共享库
$ simpleperf report --tids threadID --sort dso
- 查看函数调用关系
simpleperf report -g 或者 reprot.py -g
注意事项
Simpleperf支持两种方式记录方法调用信息,一种基于DWARF(record --call-graph dwarf or record -g
),另一种基于帧指针(record --call-graph fp
).
通常使用--call-graph fp
比--call-graph dwarf
速度更快,如果你的Android设备是AArch-64架构(arm64-v6a)应该使用--call-graph fp
,在ARM架构(armeabi或者armeabi-v7a)的设备上不能用--call-graph fp
,这是因为ARM架构的设备上通常没有帧指针寄存器。
在ARM架构的设备上应该使用--call-graph dwarf
,在这种方式下,Simpleperf使用libunwind解析栈信息。为了使用--call-graph dwarf
,我们必须提供带有调试信息的native库,基于此建议在APK中构建带有调试信息的native库。
分析使用Unity的App
略过
写在最后
Simplerperf工具随着NDK版本的更新不断更新,本文提到的使用方法在最新的NDK中有的已经改变(原理应该没变,使用更加方便),请参考ndk-location/simpleperf/doc/README.md
网友评论