这是我参与「第四届青训营 」笔记创作活动的第16天
性能优化与工具
为什么要做性能优化
- 性能优化改善体验从而提升业务指标
- 长时间的性能优化带来短时间无法被赶上的优势
- 处理器的升级速度放缓,需要软件性能提升
- 提升用户体验
什么是性能优化
-
性能优化的目标:
- 快:交互处理的速度块
- 稳:稳定,不容易闪退
- 省:节省用户内存空间和闪存空间
-
性能优化的分类:
- 流畅性优化:快-极致的响应与流畅的体验
- 线程结构:系统实现、输入事件、应用事件、定时事件
- 界面刷新:VSync信号->16ms刷新一次(60fps)
- 卡顿(丢帧)产生的原因:输入事件无法及时反应、输入事件的耗时很长、主线程其他任务的耗时
- 解决卡顿:将耗时操作转到其他线程操作,主线程只负责交互和刷新
- 资源优化:省-最小负载带来最大收益
- 方向:软件和硬件资源的优化(主要减少内存消耗)
- 端侧资源:功耗、内存、储存、CPU、GPU、网络、音量、亮度
- 服务测资源:CDN宽带、API流量
- 方向:软件和硬件资源的优化(主要减少内存消耗)
- 稳定性优化:稳-稳定的实现,减少不必要打断
- Crash:崩溃
- Timeout:超时
- UI Jank 卡顿掉帧
- ANR 应用无响应
- 系统级优化:拓展-底层booster
- 移动操作系统的性能优化
- 硬件厂商的性能优化
- 流畅性优化:快-极致的响应与流畅的体验
最佳性能优化工具选型
-
性能监控的价值
- 监控和优化相生相伴
- 监控有攻有防
- 攻是为了发现问题,指导优化方向
- 防是为了发现劣化问题,及时止损
- 线上监控发现问题并聚合排序,突出比较严重的问题
- 线下监控辅助线上监控,解决问题
-
GPU呈现模式(只能初步归因)
- 原理:系统通过记录每一帧的相关数据,通过图形的形式呈现出来
- 优点:无需二次开发,简单易用
- 缺点:并不完全准确,且无法明确指出造成卡顿问题的具体原因
-
Layertool(抖音自研的工具)
- 目的:准确的找出过渡绘制的布局
- 原理:遍历ViewTree信息,输出View层级关系
- 优点:清楚明了,可以宏观感知ViewTree现状,也可以定制,帮助分析overdraw
- 缺点:还不能够清楚明确的分析出UI的性能瓶颈
-
CPU Profiler(自带)
- 原理:基于JVMTI
- 优点:完整的方法调用栈输出,支持Java、C、C++方法耗时检测,上手简单
- 缺点:性能损耗大
-
TraceView(自带)
- Instrument
- 虚拟监听函数入口回调,Enter/Exit/Unwind
- 耗时点:读时间、写数据到buffer、加锁等指令
- Sample
- 通过定时抓取多次堆栈diff,近似确定杉树的进入和退出时间
- 耗时点:堆栈diff、同Instrument
- ps:间隔抓取堆栈的时间越长,性能损耗越少,而越会导致短函数检测不到
- Instrument
-
Systrace(重要)
- ftrace:通过debugfs采集和读取trace数据,记录trace events
- atrace:用户侧的trace跟踪,聚合所有trace event
- 系统级的Trace数据:锁监控等
-
btrace(aka rhea)-进阶
- rhea-systrace:全函数插桩,自动生成Trace代码,限制层级数量
- rhea-mtrace:全函数插桩,抛弃systrace,自己统计函数耗时,最后数据展现同systrace
- rhea-atrace:优化systrace性能,聚合更多性能数据:类加载、Lock、IO等
如何做性能优化
现状分析
-
耗时成因
- CPU Time:循环、反射、序列化/反序列化、类解析
- IO Wait:IO操作时等待IO返回结果
- IPC:Binder调用耗时
- Lock Wait:线程等待唤醒
- CPU Schedule:主线程是可执行状态,但是获取不道CPU时间片
-
运行环境归因(根据耗时成因归因)
- 目的:根据运行所在线程环境采用不同的策略
- 归因
- 主线程优化
- 运行时优化
- 后台线程优化
-
启动分析
- 冷启动(<3s)
- 创建进程
- ContentProvider init
- 应用创建(onCreate)
- 温启动(进程存在,Activity被销毁)(<1s)
- 创建Activity
- inflate view hierarchy
- 热启动(无耗时)
- Activity#onStart()
- 冷启动(<3s)
-
渲染分析
- 渲染耗时
- inflater:布局初始化
- init:往布局里填充数据
- bind:绑定
- measure/layout/draw
- overdraw:过度绘制
- 渲染频率
- AnimaterFPS
- Vsync Leak
- requestlayout loop
- 渲染耗时