应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

于“「2021 友盟+ 动应⽤性能挑战赛 中的参赛作品, 该⽂章表述了作者如何借友盟+ U-APM进⾏了性能化。

为⼀款倒计时⽇历 APP 需要个⽇实时显示倒计时并精确到秒。但是我 app 在滑刷新在很程度上取设备 CPU 和其他消耗 CPU 时间程。于是我们尝试使友盟 + U-APM 存分析 APP 进⾏分析:

应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

过观存的分布, 部分程序的运⾏于可预测的范围内, 我需要更加粒度地进⾏测 试

启动 Android Profiler Tool Window , CPU Profiler并选择正确的时间线接我测试 设备并再次进⾏刷新, 可以看到Profile线程被添加到应⽤进消耗了外的 CPU 时间 看看 Logcat

I/Choreographer: Skipped 147 frames! The application may be doing too much

CPU Profiler 时间线

应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

表上⼀个视图表示⽤户与应⽤程序的交互。所有⽤户输⼊事件在此处显⾊圆圈。可以看到⼀个圆圈,代表我们为刷新⽽执⾏的滑动。在事件下,有⼀个 CPU 时间线示了CPU 总时间应⽤程序和 其他程的 CPU 使率。可以应⽤程序正在使线

底部可以看到应⽤进程的线程活动时间线个线于由颜⾊指示的三种状态 绿⾊ 、等待⻩⾊ 或睡眠(灰

在列表部, 可以找到应⽤程序的主线程。在我的设备 (Nexus 5X) 上,使的 CPU 时间⼤ 约 5 秒。我可以记录⼀个⽅法跟踪来查看。

在滑之前单击记录以刷新操作据刷新完成后即停⽌记录

应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

们将从⼀个选项卡中示的始分析。横轴代表时间的流逝。

调⽤者及其被调⽤ 上到下)  示在垂直上。调⽤也通过颜⾊区分,具体取于是 API、第三 API 是我本地函。每个⽅调⽤总时间时间及其被时间和:

应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

从这张图表中,可以推出性能问题出在generateItems部。证实的推们⼜使友盟+ U-APM进⾏线测试测试结果和前相同,下友盟+ U-APM的卡分析测试中展示了主要是法造成了CPU的致了卡发⽣

应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

揭示了法占宝贵 CPU 时间聚合了相同的调⽤

应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

发现两个可疑的地, getRemainingTime 个⽅执⾏时间达到2 秒以上,LocalDateTime.format CPU 时间 1 秒以上:

应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

时间还包括线程未于活动状态时间段。另外, 可以切要在线时间示的计时信息。最后⼀个选项卡中的示按 CPU 时间消耗降序排列的调⽤列表。该图表提供详细信息 (以微秒为单

应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

从图表中取消耗 CPU 时间法的计时信息。将它们与调⽤中的两个⽅法相关联

class  method total time (in ms) percentage of recorded duration

Sample1Activity refreshData 3027   89.28

Sample1Activity generateItems  3025   89.22

Sample1Activity getRemainingTime   1723   50.83

LocalDateTime  format 1003   29.59


可以看到 getRemainingTime LocalDateTime.format 消耗了超 80% 时间了解 顿问题 需要从这⾥⼊⼿么该怎么办明的者可能已提出了⼏种决⽅案。 由于我们执⾏算, 所以我们 将数当示和准备显示的项⽬调⽤getRemainingTime LocalDateTime.format ⽅法。

实现它 需要更新 Item 性, 保存必要的据以便稍后执⾏格式化:

data class Item(val now: LocalDateTime, val offset: Int)

 需要在 generateItems bindItem 应⽤以下更改:

private fun generateItems(): List<Item> {

val now = LocalDateTime.now()

return List(1_000) { Item(now, it + 1) }

}

private fun bindItem(holder: ViewHolderBinder<Item>, item: Item) = with(

val date = item.now.plusDays(item.offset.toLong()).toLocalDate().atS

val remainingTime = getRemainingTime(item.now, date)

应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

们内联了 createItem 函在所有函都在 bindItem 部。在我的代修改效之后, 重新启动 CPU Profiler 并记录⽅法的运⾏

检查化是否成功, 需要 Call Chart

应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

将⿏标移到 generateItems 上,会发现现在耗时约为0.3 秒。⽐优化前少了 13 倍以上的 CPU 时间 了确保我的更改不会对 bindItem 法的耗 造成负⾯增益,我图标来检查bindItem时。如图所示,最多消耗 0.1 秒:

应用性能监控:使用Android Profiler和友盟+U-APM解决Android卡顿问题

此外, 可以进⾏滚动测试 以确保我的代码优化不整体应⽤程序的性能, 且在 动过程中加以记录测试发现滚动之后不再出和掉的情了。成功!优化!Android Profiler 友盟+U-APM 都是很好的测试⼯具。如果我追求流⽤户 使⽤这秀的 debug 具是分必要的。在本中, 我主要注性能调优

但是, 中未涵盖的 Android Profiler Memory Profiler Network Profiler 友盟+U-A PM 存分析、OOF 常和存占也同样值究。记录内存分配对查存泄漏有很助, 例如代中有有回收 bitmap⽆论如何, 使的分析具可以带来项优化成果, 期待⾃⾏探索。

 

作者:查宇

上一篇:弹性伸缩服务问题排查指南


下一篇:注释大全,神兽护体,佛祖保佑,永无bug