本次分享会目的
通过对增加对 Android Profile Tools 的了解,提高大家工作过程中定位和解决Bug的效率。
注意事项
- 为了不耽误大家时间,语速可能会快一些
- 如果讲到某个工具或者技巧,你不太了解,一定要记住它可以解决什么问题。后期如果开发过程中用到可以再查询具体使用技巧。
- 如果对我分享的某个工具和技巧,很熟练,你的经验我又恰好没有讲到,欢迎打断我然后分享自己的经验,这样可以使本次分享会的作用最大化。
学习 Android 开发知识个人认为最重要的一点
尽量用谷歌查bug,查问题原因,查知识点。
使用靠谱的学习渠道——谷歌官网。
Profile Tools
谷歌官方提供的Profile Tools主要有两类:Android Studio Tools 和 Command Line Tools。
Android Studio Tools
1、CPU Profiler
2、Memory Profiler
3、Network Profiler
4、Battery Historian
5、Energy Profiler
6、Profile GPU Rendering
7、Graphics API Debugger (Analyze OpenGL with Tracer is deprecated)
8、Layout Inspector (Hierarchy Viewer is deprecated)
Command Line Tools
1、systrace
2、dumpsys
3、dmtracedump
……
Android Profiler
https://developer.android.com/studio/profile
https://developer.android.com/studio/profile?hl=en
官方简介:
An app is considered to have poor performance if it responds slowly, shows choppy animations, freezes, crashes, or consumes a lot of power. To avoid these performance problems, use the profiling tools listed on this page to identify where your app is making inefficient use of resources, such as the CPU, memory, graphics, network, and device battery.
如果应用程序响应缓慢,显示不稳定的动画,冻结,崩溃或消耗大量功率,则应用程序被认为性能较差。 要避免这些性能问题,请使用此页面上列出的性能分析工具来确定应用程序在何处低效使用资源,例如CPU,内存,图形,网络和设备电池。
Profile:扼要介绍;概述。
在 “Profile Tools” 这个场景下感觉翻译成“配置,全面测量”比较合适。
个人的感觉Profile Tools更偏向宏观层面的整体测试。
实际举例:如果耗电量过多,需要先从整体判断,有可能耗电多的点是AlarmManager的使用,还是Wakelock使用太多,通过Profile Tools先进行判断,然后再在微观代码层面进行优化。
使用注意事项:
之前的Android Monitor :
- While profiling an app, you should [disable Instant Run]。There is a small performance impact when using Instant Run and a slightly larger impact when updating methods. This performance impact could interfere with information provided by performance profiling tools. Additionally, the stub methods generated while using the feature can complicate stack traces.
在分析应用程序时,应该禁用“Instant Run”。 使用Instant Run时性能影响很小,更新方法时影响稍大。 此性能影响可能会干扰性能分析工具提供的信息。 此外,使用该功能时生成的存根方法可能会使堆栈跟踪变得复杂。- Android Studio 3.0 采用全新的 **Android Profiler ** 窗口取代 Android Monitor 工具。 如果使用Android Profiler需要使用比较新的Android Studio。
打开 Android Profiler 窗口步骤:
-
点击 View > Tool Windows > Android Profiler(也可以点击工具栏中的 Android Profiler )。
在 Android Profiler 窗口顶部,选择想要分析的设备 1 和应用进程 2。
如果通过 USB 连接了某个设备但该设备未在设备列表中列出,请确保已启用 USB 调试。
如果使用的是 Android Emulator 或已取得 root 权限的设备,Android Profiler 将列出所有正在运行的进程,即使这些进程可能无法调试。 当发布可调试应用时,将会默认选择此进程。
启用高级分析
要显示高级分析数据,Android Studio 必须在编译后的应用中插入监控逻辑。 我个人的理解就是打开了高级分析,可以获取更加详细的监控数据。
高级分析工具提供的功能包括:
1、Event 时间线(所有分析器窗口中均有)
2、分配对象数量(Memory Profiler 中)
3、垃圾回收 Event(Memory Profiler 中)
4、有关所有传输的文件的详情(Network Profiler 中)
要启用高级分析,请按以下步骤操作:
1、选择 Run > Edit Configurations。
2、在左侧窗格中选择的应用模块。
3、点击 Profiling 标签,然后勾选 Enable advanced profiling。
4、现在重新构建并运行的应用,即可获取完整的分析功能。 但请注意,高级分析会减缓的构建速度,所以仅当想要开始分析应用时才启用此功能。
注:对于原生代码,不可使用高级分析功能。 如果的应用是纯原生应用(不含 Java Activity 类),则不可使用高级分析功能。 如果的应用使用了 JNI,则可使用部分高级分析功能,例如 Event 时间线、GC Event、Java 分配对象和基于 Java 的网络 Activity,但不能检测基于原生的分配和网络 Activity。
CPU Profiler
CPU Profiler 可帮助实时检查应用的 CPU 使用率和线程活动,并记录函数跟踪,以便可以优化和调试的应用代码。
要打开 CPU Profiler,请按以下步骤操作:
- 点击 View > Tool Windows > Android Profiler(也可以点击工具栏中的 Android Profiler)。
- 从 Android Profiler 工具栏中选择想要分析的设备和应用进程。 如果通过 USB 连接了某个设备但该设备未在设备列表中列出,请确保已启用 USB 调试。
- 点击 CPU 时间线中的任意位置即可打开 CPU Profiler。
为什么要分析 CPU 使用率
最大限度减少应用的 CPU 使用率具有许多优势,如提供更快更顺畅的用户体验,以及延长设备电池续航时间。 它还可帮助应用在各种新旧设备上保持良好性能。 与应用交互时,可以使用 CPU Profiler 监控 CPU 使用率和线程 Activity。 不过,如需了解应用如何执行其代码的详细信息,应记录和检查函数跟踪。
对于应用进程中的每个线程,可以查看一段时间内执行了哪些函数,以及在其执行期间每个函数消耗的 CPU 资源。 还可以使用函数跟踪来识别调用方和被调用方。 调用方指调用其他函数的函数,而被调用方是指被其他函数调用的函数。 您可以使用此信息确定哪些函数负责调用常常会消耗大量特定资源的任务,并尝试优化应用代码以避免不必要的工作。
翻译:查看哪个函数消耗时间太多。
Memory Profiler
Memory Profiler 是 Android Profiler 中的一个组件,可帮助您识别导致应用卡顿、冻结甚至崩溃的内存泄漏和流失。 它显示一个应用内存使用量的实时图表,让您可以捕获堆转储、强制执行垃圾回收以及跟踪内存分配。
打开 Memory Profiler 步骤:
- 点击 View > Tool Windows > Android Profiler(也可以点击工具栏中的 Android Profiler)。
- 从 Android Profiler 工具栏中选择您想要分析的设备和应用进程。 如果您通过 USB 连接了某个设备但该设备未在设备列表中列出,请确保您已启用 USB 调试。
-
点击 **MEMORY **时间线中的任意位置可打开 Memory Profiler。
为什么应分析您的应用内存
Android 提供一个托管内存环境—当它确定您的应用不再使用某些对象时,垃圾回收器会将未使用的内存释放回堆中。 虽然 Android 查找未使用内存的方式在不断改进,但对于所有 Android 版本,系统都必须在某个时间点短暂地暂停您的代码。 大多数情况下,这些暂停难以察觉。 不过,如果您的应用分配内存的速度比系统回收内存的速度快,则当收集器释放足够的内存以满足您的分配需要时,您的应用可能会延迟。 此延迟可能会导致您的应用跳帧,并使系统明显变慢。
尽管您的应用不会表现出变慢,但如果存在内存泄漏,则即使应用在后台运行也会保留该内存。 此行为会强制执行不必要的垃圾回收 Event,因而拖慢系统的内存性能。 最后,系统被迫终止您的应用进程以回收内存。 然后,当用户返回您的应用时,它必须完全重启。
为帮助防止这些问题,您应使用 Memory Profiler 执行以下操作:
- 在时间线中查找可能会导致性能问题的不理想的内存分配模式。
- 转储 Java 堆以查看在任何给定时间哪些对象耗尽了使用内存。 长时间进行多个堆转储可帮助识别内存泄漏。
- 记录正常用户交互和极端用户交互期间的内存分配以准确识别您的代码在何处短时间分配了过多对象,或分配了泄漏的对象。
如图所示,Memory Profiler 的默认视图包括以下各项:
- 用于强制执行垃圾回收 Event 的按钮。
- 用于捕获堆转储的按钮。
- 用于记录内存分配情况的按钮。 此按钮仅在连接至运行 Android 7.1 或更低版本的设备时才会显示。
- 用于放大/缩小时间线的按钮。
- 用于跳转至实时内存数据的按钮。
- Event 时间线,其显示 Activity 状态、用户输入 Event 和屏幕旋转 Event。
- 内存使用量时间线,其包含以下内容:
- 一个显示每个内存类别使用多少内存的堆叠图表,如左侧的 y 轴以及顶部的彩色键所示。
- 虚线表示分配的对象数,如右侧的 y 轴所示。
- 用于表示每个垃圾回收 Event 的图标。
备注:Android 8.0 以上可以看到全部信息,8.0以下默认不是所有数据可见,需要启用高级分析才能查看以下内容:
* Event 时间线
* 分配的对象数
* 垃圾回收 Event
如何计算内存
您在 Memory Profiler顶部看到的数字取决于您的应用根据 Android 系统机制所提交的所有私有内存页面数。 此计数不包含与系统或其他应用共享的页面。
内存计数中的类别如下所示:
Java:从 Java 或 Kotlin 代码分配的对象内存。
-
Native:从 C 或 C++ 代码分配的对象内存。
即使您的应用中不使用 C++,您也可能会看到此处使用的一些原生内存,因为 Android 框架使用原生内存代表您处理各种任务,如处理图像资源和其他图形时,即使您编写的代码采用 Java 或 Kotlin 语言。
Graphics:图形缓冲区队列向屏幕显示像素(包括 GL 表面、GL 纹理等等)所使用的内存。 (请注意,这是与 CPU 共享的内存,不是 GPU 专用内存。)
Stack: 您的应用中的原生堆栈和 Java 堆栈使用的内存。 这通常与您的应用运行多少线程有关。
Code:您的应用用于处理代码和资源(如 dex 字节码、已优化或已编译的 dex 码、.so 库和字体)的内存。
Other:您的应用使用的系统不确定如何分类的内存。
-
Allocated:您的应用分配的 Java/Kotlin 对象数。 它没有计入 C 或 C++ 中分配的对象。
当连接至运行 Android 7.1 及更低版本的设备时,此分配仅在 Memory Profiler 连接至您运行的应用时才开始计数。 因此,您开始分析之前分配的任何对象都不会被计入。 不过,Android 8.0 附带一个设备内置分析工具,该工具可记录所有分配,因此,在 Android 8.0 及更高版本上,此数字始终表示您的应用中待处理的 Java 对象总数。
与以前的 Android Monitor 工具中的内存计数相比,新的 Memory Profiler 以不同的方式记录您的内存,因此,您的内存使用量现在看上去可能会更高些。 Memory Profiler 监控的类别更多,这会增加总的内存使用量,但如果您仅关心 Java 堆内存,则“Java”项的数字应与以前工具中的数值相似。
然而,Java 数字可能与您在 Android Monitor 中看到的数字并非完全相同,这是因为应用的 Java 堆是从 Zygote 启动的,而新数字则计入了为它分配的所有物理内存页面。 因此,它可以准确反映您的应用实际使用了多少物理内存。
注:目前,Memory Profiler 还会显示应用中的一些误报的原生内存使用量,而这些内存实际上是分析工具使用的。 对于大约 100000 个对象,最多会使报告的内存使用量增加 10MB。 在这些工具的未来版本中,这些数字将从您的数据中过滤掉。
Network Profiler
为什么应分析应用的网络活动
When your app makes a request to the network, the device must use the power-hungry mobile or WiFi radios to send and receive packets. The radios not only use power to transfer data, but also use extra power to turn on and to stay awake.
Using the Network Profiler, you can look for frequent, short spikes of network activity, which mean that your app requires the radios to turn on frequently, or to stay awake for long periods to handle many short requests close together. This pattern indicates that you may be able to optimize your app for improved battery performance by batching network requests, thereby reducing the number of times the radios must turn on to send or receive data. This also allows the radios to switch into low-power mode to save battery in the longer gaps between batched requests.
For more information about techniques to optimize your app's network activity, read Reducing network battery drain.
1、频繁网络请求不仅仅本身消耗电量,而且手机因为无法休眠导致消耗更多电量
2、使用Network Profiler可以找出网络请求的状态,找出其中可以优化的部分,达到优化应用,改善电池续航。
仅支持HttpURLConnection和OkHttp
如果 Network Profiler 检测到流量值,但无法识别任何受支持的网络请求,您会收到以下错误消息:
"Network Profiling Data Unavailable: There is no information for the network traffic you've selected."
Network Profiler 目前只支持 HttpURLConnection
和OkHttp
网络连接库。 如果您的应用使用的是其他网络连接库,则可能无法在 Network Profiler 中查看网络 Activity。
Battery Historian
Batterystats是Android框架中包含的工具,用于收集设备上的电池数据。 您可以使用adb将收集的电池数据转储到开发机器,并使用Battery Historian创建可以分析的报告。 Battery Historian将报告从Batterystats转换为可在浏览器中查看的HTML可视化文件。
好处有:
1、电池消耗的详情
2、识别应用中可能会延迟甚至删除的任务,以延长电池寿命。
从Batterystats提取数据的步骤:
1、将移动设备连接到计算机。
2、通过终端窗口,关闭正在运行的adb服务
adb kill-server
3、重新启动adb并检查已连接的设备。
adb devices
4、重置Batterystats数据采集
adb shell dumpsys batterystats --reset
设备会始终在后台收集batterystats和其他调试信息。重置会删除旧的Batterystats收集数据。如果不重置,输出的文件将会十分巨大。
5、断开设备与计算机的连接,以便设备仅使用电池的电量。
6、执行需要测试的操作:使用目标APP等
7、重新连接手机。
8、确保手机已经连接
adb devices
9、转储所有电池数据。可能需要一些时间:
adb shell dumpsys batterystats [path/]batterystats.txt
使用可选路径参数在指定的目录中创建batterystats.txt文件。如果未指定路径,则会在主目录中创建该文件。
10、从原始数据创建报告:
Android 7.0 或者更高版本:
adb bugreport > [path/]bugreport.zip
Android 6.0 或者更低版本:
adb bugreport > [path/]bugreport.txt
Bugreport可能需要几分钟才能完成。在完成之前,请勿断开设备或取消该过程。
11、启动Battery Historian 并登陆到相应界面:
12、提交Bugreport文件,并点击Submit。完成数据分析。
GPU Rendering
Profile GPU Rendering 工具以滚动直方图的形式直观地显示渲染界面窗口帧所花费的时间(以每帧 16 毫秒的速度作为对比基准)。
在性能较低的 GPU 上,可用的填充率(GPU 填充帧缓冲区的速度)可能很低。 随着绘制帧所需的像素数增加,GPU 可能需要花较长时间来处理新命令,并要求系统的其余任务等待,直到系统可以跟上需求。 此分析工具可帮助您确定 GPU 何时因尝试绘制像素而负担过重,或何时因大量的过度绘制而被拖累。
注:此分析工具不适用于使用 NDK 的应用。 推荐使用 GPU 制造商提供的分析工具。
启用分析器
开始前,请确保您使用的是运行 Android 4.1(API 级别 16)或更高版本的设备,并启用开发者选项。 要在使用应用时开始分析设备 GPU 渲染,请执行以下操作:
- 在您的设备上,转到 Settings 并点按 Developer Options。
- 在 Monitoring 部分,选择 Profile GPU Rendering。
- 在 Profile GPU Rendering 对话框中,选择 On screen as bars 以在设备屏幕上叠加图表。
- 打开您要分析的应用。
注意事项:
1、对于每个可见应用,此工具将显示一个图表。
2、沿水平轴的每个竖条都代表一个帧,每个竖条的高度表示渲染该帧所花的时间(单位:毫秒)。
3、水平绿线表示 16 毫秒。 要实现每秒 60 帧,代表每个帧的竖条需要保持在此线以下。 当竖条超出此线时,可能会使动画出现暂停。
此工具通过加宽对应的竖条并降低透明度来突出显示超出 16 毫秒阈值的帧。
4、每个竖条都有与渲染管道中某个阶段对应的彩色区段。 区段数因设备的 API 级别而异。
下表介绍了使用运行 Android 6.0 及更高版本的设备时分析器输出中某个竖条的每个区段。
4.0(API 级别 14)和 5.0(API 级别 21)之间的 Android 版本具有蓝色、紫色、红色和橙色区段。 低于 4.0 的 Android 版本只有蓝色、红色和橙色区段。 下表显示的是 Android 4.0 和 5.0 中的竖条区段。
Energy Profiler
The Energy Profiler helps you to find where your app uses more energy than necessary.
The Energy Profiler monitors the use of the CPU, network radio, and GPS sensor, and it displays a visualization of how much energy each of these components uses. The Energy Profiler also shows you occurrences of system events (wake locks, alarms, jobs, and location requests) that can affect energy consumption.
The Energy Profiler does not directly measure energy consumption. Rather, it uses a model that estimates the energy consumption for each resource on the device.
1、Energy Profiler可帮助您找到应用程序使用的能量超出必要的程度。
2、Energy Profiler监控CPU,network radio和GPS传感器的使用情况,并显示每个组件使用多少能量的可视化。 Energy Profiler还会显示可能影响能耗的系统事件(wake locks, alarms, jobs和位置请求)。
3、Energy Profiler不直接测量能耗。 相反,它使用一种模型来估算设备上每种资源的能耗。
WakeLock:A wake lock is a mechanism to indicate that your application needs to have the device stay on.
唤醒锁是一种机制,用于指示您的应用程序需要让设备保持打开状态。
AlarmManager:This class provides access to the system alarm services.
系统时钟,通过广播方式发送提醒。
JobScheduler :This is an API for scheduling various types of jobs against the framework that will be executed in your application's own process.
工作调度器:通过系统后台服务,执行自己的任务。相比AlarmManager更加省电。