初识性能优化及工具|青训营笔记

98 阅读6分钟

这是我参与「第四届青训营 」笔记创作活动的第6天,前几天围绕客户端的应用展开了课程,介绍了UI,数据通信,网络,直播,端智能各种不同的应用,但是终端设备的算力/性能是有限的,手机卡死,闪退这些不仅仅是程序缺陷,也有可能是性能负载过高。那么如何使终端设备的性能得到充分的发挥,就需要性能优化。 性能优化的必要性有很多,对于用户而言,及时的反馈可以带来体验的提升,对企业而言,用户体验的提升会拉动业务指标的提升。从长远来看,硬件设备的性能虽然取得了长远的进步,先进制程,多核计算,并行处理,但是进步的速度终归有限,但是软件所占用的资源却飞速发展,从某绿色社交软件就可以看出,十年前只有30MB,如今却是动辄上G的内存,软硬件之间的矛盾需要性能优化的协调。同时,性能优化可以提高能源的利用率,一定程度上可以推动环保。 那么性能优化的目标是什么呢?快(极致的响应和流畅的体验),稳(减少不必要的打断,实现稳定),省(最小负载带来最大的收益)。使用起来流畅,稳定,省电就是性能优化的最终目标。以此为目标也衍生出了四种性能优化,首先就是流畅性优化,首先需要了解Android的线程结构。

image.png 我们的代码分布在UI线程的不同部分,实现不同的响应。在此同时,UI线程每间隔的相同的时间进行一次UI绘制,显示我们想要的结果。当某些程序比较耗时,使后续事件对应的数据获取不到,会造成事件的推迟,但UI绘制不会,就产生了丢帧的现象,如何去解决呢,我们可以在创一个新的子线程去处理这些耗时的代码,主线程就有能力处理输入事件,就不会造成丢帧了。流畅性优化的核心点在于线程与数据的交换时机由谁来控制,数据交换应该发生在屏幕渲染完一帧后,而不是CPU写入一帧数据后,因此是否交换应该由屏幕控制。但是冯诺依曼计算机的各个部分各司其职,屏幕只是输入和输出设备,并非控制器,所以需要借助其他设备实现,这就是Vsync,没有该信号,就会造成图像的不匹配,反应到屏幕上就是身首异处之类的画面。 接着是资源优化,资源就是Android设备上的软件和硬件资源,通俗意义上应用依赖的移动终端有限资源和系统设置的数值,即功耗,存储,流量,系统参数,CPU,内存等。资源优化可以做哪些呢,如下图所示:

image.png

image (35).png

image (36).png 这两张图选取了每次运行时10个数据点的样本及30次测量的平均功耗,可以看出黑屏确实会减少手机使用的电量,在Reddit Sync中使用以黑色为主的界面时,总体功耗降低了41%。 然后是稳定性优化,稳定性常见的问题如图:

image.png 其中ANR是application not responding的缩写,也就是应用程序无响应的意思,一般是Android应用的界面进程处于阻塞态过长导致的,应用位于前台,系统会显示一个对话框,ANR对话框会为用户提供强行退出应用或等待的选项。 最后就是系统级优化,下图展示的是游动操作系统和硬件厂商的性能优化:

image (37).png 深层次的需要和芯片,内核相关联的优化:

image (38).png

聊完了几种性能优化,就来看看有哪些性能优化工具。首先要了解性能监控的价值,监控和优化相生相伴;监控有攻有防;攻是为了发现现有问题,知道优化方向;防是为了发现劣化问题,及时止损;线上监控发现问题并聚合排序,线下监控为线上辅助,并发版前置发现问题。接着是GPU呈现模式,GPU呈现模式是通过记录每一帧的相关数据通过图形方式呈现。优点是不需二次开发简单易用,缺点就是不准确,而且无法支出为卡顿问题的原因。接下来介绍几种工具,首先是Layertool,通过遍历Viewtree,输出view的层级关系,优点是清楚明了,可宏观感知viewtree,也可定制,帮助分析overdraw,缺点在于不能清楚明确分析出UI的性能瓶颈。想要深入性能找到原因,首先需要了解GPU Profiler,基于JVMTI实现,优点是可以完整的输出方法调用栈,支持Java,C++,C的方法耗时检测,上手简单,缺点是性能损耗太大;想要更深入一点,就需要使用traceview。traceview有两大组件,instrument和sample。Instrument实现虚拟监听函数的回调,Enter/Exit/Unwind,耗时点主要在读时间,写数据到buffer,加锁等指令;sample则通过定时抓取堆栈diff,近似确定函数的进入和退出时间,他的耗时点在于堆栈diff和同instrument,间隔抓取堆栈的时间越长性能损耗越少,越会导致短函数检测不到。再进一步就需要学习使用Systrace,ftrace:debugfs采集和读取trace数据,记录trace events,atrace用户侧的trace跟踪,聚合所有的trace event,系统级的trace数据有锁监控等。 目前抖音使用的性能优化工具是btrace,其中rhea-systrace能够全函数插桩,自动生成trace代码,可以对trace层数进行限制,性能损耗50%;rhea-mtrace可以全函数插桩,同时抛弃了systrace,自己统计函数耗时,最后数据展现和systrace相同。rhea-atrace则优化了systrace性能,聚合更多性能数据,类加载,lock,io等。 检查功耗问题则一般是用Battery-Historian等。 介绍完了工具,就该介绍如何去用了,首先要分析下现状,性能损耗的原因在哪?首先是耗时,如CPU Time(循环,反射,序列化,反序列化,类解析等),IO Wait(io操作,等待io结果),IPC(binder调用耗时),lock wait(主线程等所装,等待其他线程或者自己超时唤醒),CPU Scheule(主线程可执行状态,但获取不到时间片)。接着是运行环境的归因,可分为主线程优化,运行时优化,后台线程优化。等