美文网首页Android开发经验谈Android开发Android开发
张绍文android开发高手课读书笔记3-卡顿优化篇

张绍文android开发高手课读书笔记3-卡顿优化篇

作者: niknowzcd | 来源:发表于2019-02-16 18:35 被阅读5次

    本系列博文 基于是前微信高级工程师张绍文专栏 《Android开发高手课》的读书笔记。

    文章所写内容是本人读完的感悟,需要原文的朋友请自行购买。

    卡顿优化篇

    先贴两篇比较简单的分析文章

    Android性能优化-界面渲染原理浅析

    Android界面渲染优化

    下面进入正题

    卡顿根本原因

    造成卡顿的原因可能有千百种,不过最终都会反映到CPU 时间上.

    CPU时间分两种

    • 用户时间 执行用户态应用程序代码所消耗的时间
    • **系统时间 **执行内核态系统调用所消耗的时间,包括 I/O、锁、中断以及其他系统调用时间

    CPU使用状态有以下几个指标

    • CPU 使用率: 如果 CPU 使用率长期大于 60% ,表示系统处于繁忙状态,就需要进一步分析用户时间和系统时间的比例。对于普通应用程序,系统时间不会长期高于 30%,如果超过这个值,就得考虑是否I/O调用过多或者锁调用的过于频繁的问题。(Android studio 3.0的版本之后可以直接观测到CPU的使用情况)

    • CPU 饱和度: CPU 饱和度反映的是线程排队等待 CPU 的情况,也就是 CPU 的负载情况。

      CPU 饱和度首先会跟应用的线程数有关,如果启动的线程过多,易导致系统不断地切换执行的线程,把大量的时间浪费在上下文切换,要知道每一次 CPU 上下文切换都需要刷新寄存器和计数器,至少需要几十纳秒的时间。

    卡顿排查工具

    分两个流派,instrument和sample.

    1. instrument: 获取一段时间内所有函数的调用过程,可以通过分析这段时间内的函数调用流程,再进一步分析待优化的点。
    2. sample: 有选择性或者采用抽样的方式观察某些函数调用过程,可以通过这些有限的信息推测出流程中的可疑点,然后再继续细化分析。

    具体的工具如下:

    Traceview

    属于instrument派系,利用 Android Runtime 函数调用的 event 事件,将函数运行的耗时和调用关系写入 trace 文件中。

    Traceview属于比较早起的工具,性能开销过大,有时无法反映真实的运行状况,另外无法反混淆。

    在Android 5.0之后,新增了 sample类型,减少开销,但是信息量就不一定达到分析需求了。

    Nanoscope

    相比起Traceview,Uber开源的Nanoscope的性能消耗就小了许多。

    但由于Nanoscope是直接修改Android虚拟机源码,会有不少的局限性。

    比如需要自己刷ROM或者用它提供的x86的模拟器,就算自己刷ROM也只支持Nexus 6P。

    如果想要简便的使用Nanoscope的话,需要一系列自动化脚步协助。

    systrace

    systrace则是利用Linux的ftrace调试工具,相当于在系统各个关键位置都添加了一些性能探针.

    一说到Linux可能很多人就比较蒙,拿Android下的知识来讲,你可以理解为类似Activity Manager类似的监控。

    Simpleperf

    Native函数的监控.(不了解)

    卡顿监控

    张老师在课中讲的多是比较深入的知识和解决问题的思路。

    就好比一个应用满分100分,张老师讲的是如何把应用从90分拉向100分.

    然而实际上大部分人需要的是如何到90分.

    任重而道远

    微信的卡顿监控也经过了几个过程

    消息队列监控

    1. 最开始通过替换主现场消息队列中Looper的MessageLogging来获取卡顿时间。

      以及打印对应的函数信息

      //参考的代码
      Printer logging = me.mLogging;
      if (logging != null) {
          logging.println(">>>>> Dispatching to " + msg.target + " " +
                          msg.callback + ": " + msg.what);
      }
      

    实现原理可以参考BlockCanary这个库或者这篇博文 Android卡顿检查-BlockCanary浅析

    1. 上线之后发现性能有所下降,替换方案。

      开一个监控线程,每隔1s向主线程消息头插入一条空消息,1秒后去检查主现程头部是否是之前插入的空消息。如果是,说明主线程卡顿了0~1秒,为什么会是一个区间呢?因为你发送空消息的时候也需要考虑在内。

      那如果监控一个3秒的卡顿,在第4秒的时候去检查空消息是否被消费,如果没有,说明确实发生了一个3秒以上的卡顿。

    消息队列监控也存在一些问题。

    比如主线程卡顿了3秒,在这3秒钟有多个函数,而通过这种方式只能得到最后一个函数的一些信息.

    但实际上耗时比较久的函数不一定是最后一个.

    不过对于用户量比较大的应用来说,根据反馈回来的数据比例还是能得到具体耗时的函数是那个。

    插桩

    利用lnline Hook技术和上文中提到systrace。

    Profile

    FaceBook开源的Profile库,性能确实很高。

    但是其中黑科技太多,所以兼容性还是个大问题。

    帧率监控

    业界都使用 Choreographer 来监控应用的帧率

    监听界面是否存在绘制行为

    getWindow().getDecorView().getViewTreeObserver().addOnDrawListener
    

    Android Vitals 将连续丢帧超过 700 毫秒定义为冻帧,也就是连续丢帧 42 帧以上。

    其他

    4大组件中 Service 和 Receiver 虽然是后台组件,不过它们生命周期也是占用主线程的,调用的过于频繁也会导致卡顿.

    最后,给自己公众号打个广告,【码农的唠叨】聊技术,聊热文,聊互联网趣事,也发唠叨

    qrcode_for_gh_5febf245550e_258

    相关文章

      网友评论

        本文标题:张绍文android开发高手课读书笔记3-卡顿优化篇

        本文链接:https://www.haomeiwen.com/subject/wosieqtx.html