以下示例展示了如何结合使用系统跟踪、Macrobenchmark 以及内存性能分析来衡量并改善特定类型的性能问题。
使用 systrace 调试应用启动
建议您根据 systrace 日志来调试启动时间。systrace 系统可使用预插桩的代码,在特定事件发生时输出该事件所用的时间。您可通过这些跟踪记录了解自己应用内发生的情况,甚至了解整个系统中其他进程的情况。Android 平台和 Jetpack 库提供针对应用内多个关键事件的插桩,并且会相应地记录这些事件。您还可以使用自己的自定义跟踪记录(会显示在相同的 systrace 可视化工具中)对应用进行插桩处理,以全面了解应用内发生的情况。
使用 systrace 或 Perfetto
如需详细了解 systrace 的基本用法,请观看以下视频:调试应用的性能。
要分析启动时间,您必须先了解启动期间会执行哪些操作。如需了解本页内容以外的更多信息,请参阅关于应用启动时间的文档,简要了解应用的启动过程。
应用的启动过程包含以下几个阶段:
- 启动进程
- 初始化通用应用对象
- 创建并初始化 activity
- 膨胀布局
- 绘制第一帧
按启动类型可以分为以下几个阶段:
- 冷启动:系统启动后或应用进程被用户或系统终止后,首次启动应用时。启动会创建一个没有已保存状态的新进程。
- 温启动:应用已在后台运行,但必须重新创建 activity 并转到前台运行时。重新使用现有进程或使用已保存的状态重新创建进程时,会重新创建 activity。Macrobenchmark 测试库支持通过第一种方式使温启动测试保持一致。
- 热启动:进程和 activity 仍在运行,而且只需转到前台运行时(可能会根据需要重新创建某些对象);以及渲染新的前台 activity 时。这是耗时最短的启动场景。
建议您通过开发者选项中提供的设备上系统跟踪应用捕获 systrace 跟踪记录。如果您想使用命令行工具,Perfetto 适用于 Android 10(API 级别 29)及更高版本,而搭载更低版本的设备应使用 systrace。
请注意,“第一帧”这一用词不太恰当,因为不同的应用在创建初始 activity 后处理启动的方式可能存在巨大差异。有些应用会继续膨胀数帧,而有些应用则会立即启动到第二个 activity。
如果可能,建议您在从应用角度看已完成启动后添加一个 reportFullyDrawn
调用(适用于 Android 10 及更高版本)。
以下是在这些系统跟踪记录中需要关注的内容:
在图 4 中,请注意,同时执行 I/O 的其他进程可能会导致 I/O 争用,因此请确保其他进程未运行。
其他线程上的重要 activity 可能会干扰界面线程,因此请留意启动期间的后台工作。请注意,不同设备的 CPU 配置可能会有所不同,因此不同设备上可并行运行的线程数可能也会有所不同。
另请查看常见的卡顿来源指南。
使用 Android Studio 内存分析器
Android Studio 内存性能分析器是一款功能强大的工具,可减小内存泄漏或模式使用不当可能会带来的内存压力。您可以通过该工具实时查看对象分配和回收情况。
若要修复应用中的内存问题,您可以使用内存分析器来跟踪垃圾回收的原因和频率,以及是否存在导致您的堆在一段时间内不断增加的内存泄漏问题。
应用内存性能的分析分为以下几个步骤:
1. 检测内存问题
如需检测内存问题,请先记录应用的内存性能分析会话。接下来,查找内存占用量不断增加且最终触发了垃圾回收事件的对象。
图 6. 显示垃圾回收事件的内存分析器。{.:image-caption}
确定会增加内存压力的使用场景后,开始分析根本原因。
2. 诊断内存压力热点
在时间轴中选择一个范围,以直观呈现分配情况和浅层大小。
您可以通过多种方式对这些数据进行排序。以下内容通过一些示例说明了每个视图如何帮助您分析问题。
按类排列
如果您想查找哪些类正在生成本应从内存池中缓存或重用的对象,按类排列非常有用。
例如,假设某个应用每秒会使用名为“Vertex”的类创建 2,000 个对象。这会使分配数每秒增加 2,000 个,按类排序时,您会看到这一数值。是否会重新使用这些对象来避免产生垃圾?如果是,则可能需要实现内存池。
按调用堆栈排列
当存在用于分配内存的热路径(例如,在循环内或执行大量分配工作的特定函数内),按调用堆栈排列非常有用。按调用堆栈排列时可查看分配的热点。
浅层大小和保留大小
浅层大小仅跟踪对象本身的内存,因此最适合跟踪主要由基元组成的简单类。
保留大小显示对象直接分配的总内存,以及分配的单独由该对象引用的其他对象。保留大小适用于跟踪因需要分配其他对象(而不仅仅是基元字段)的复杂对象导致的内存压力。如需获取此值,请使用内存性能分析器创建内存转储。相应堆中分配的对象会加到显示的数值中。
3. 衡量优化的影响
垃圾回收是一种易于衡量的内存优化改进方式。如果优化可减小内存压力,您会发现垃圾回收 (GC) 量变少。若要衡量此指标,请衡量性能分析器时间轴中垃圾回收之间的时间间隔。执行内存优化后,您会发现垃圾回收之间的间隔时间变长。
这种内存优化方式的最终影响为:
- 如果应用不常导致内存压力,因内存不足而导致应用终止运行的频率将降低。
- 减少垃圾回收次数可以优化卡顿指标。这是因为垃圾回收会导致 CPU 争用,从而导致渲染任务在垃圾回收时出现延迟。
为您推荐
- 注意:当 JavaScript 处于关闭状态时,系统会显示链接文字
- 捕获 Macrobenchmark 指标
- 应用启动分析和优化 {:#app-startup-analysis-optimization}