本系列博文 基因而前微信高级工程师张绍文专栏 《Android开发高手课》的读书笔记。java
文章所写内容是本人读完的感悟,须要原文的朋友请自行购买。性能优化
先贴两篇比较简单的分析文章bash
下面进入正题工具
形成卡顿的缘由可能有千百种,不过最终都会反映到CPU 时间上.oop
CPU时间分两种性能
CPU使用状态有如下几个指标优化
CPU 使用率: 若是 CPU 使用率长期大于 60% ,表示系统处于繁忙状态,就须要进一步分析用户时间和系统时间的比例。对于普通应用程序,系统时间不会长期高于 30%,若是超过这个值,就得考虑是否I/O调用过多或者锁调用的过于频繁的问题。(Android studio 3.0的版本以后能够直接观测到CPU的使用状况)spa
CPU 饱和度: CPU 饱和度反映的是线程排队等待 CPU 的状况,也就是 CPU 的负载状况。
CPU 饱和度首先会跟应用的线程数有关,若是启动的线程过多,易致使系统不断地切换执行的线程,把大量的时间浪费在上下文切换,要知道每一次 CPU 上下文切换都须要刷新寄存器和计数器,至少须要几十纳秒的时间。
分两个流派,instrument和sample.
具体的工具以下:
属于instrument派系,利用 Android Runtime 函数调用的 event 事件,将函数运行的耗时和调用关系写入 trace 文件中。
Traceview属于比较早起的工具,性能开销过大,有时没法反映真实的运行情况,另外没法反混淆。
在Android 5.0以后,新增了 sample类型,减小开销,可是信息量就不必定达到分析需求了。
相比起Traceview,Uber开源的Nanoscope的性能消耗就小了许多。
但因为Nanoscope是直接修改Android虚拟机源码,会有很多的局限性。
好比须要本身刷ROM或者用它提供的x86的模拟器,就算本身刷ROM也只支持Nexus 6P。
若是想要简便的使用Nanoscope的话,须要一系列自动化脚步协助。
systrace则是利用Linux的ftrace调试工具,至关于在系统各个关键位置都添加了一些性能探针.
一说到Linux可能不少人就比较蒙,拿Android下的知识来说,你能够理解为相似Activity Manager相似的监控。
Native函数的监控.(不了解)
张老师在课中讲的可能是比较深刻的知识和解决问题的思路。
就比如一个应用满分100分,张老师讲的是如何把应用从90分拉向100分.
然而实际上大部分人须要的是如何到90分.
任重而道远
微信的卡顿监控也通过了几个过程
最开始经过替换主现场消息队列中Looper的MessageLogging来获取卡顿时间。
以及打印对应的函数信息
//参考的代码
Printer logging = me.mLogging;
if (logging != null) {
logging.println(">>>>> Dispatching to " + msg.target + " " +
msg.callback + ": " + msg.what);
}
复制代码
实现原理能够参考BlockCanary这个库或者这篇博文 Android卡顿检查-BlockCanary浅析
上线以后发现性能有所降低,替换方案。
开一个监控线程,每隔1s向主线程消息头插入一条空消息,1秒后去检查主现程头部是不是以前插入的空消息。若是是,说明主线程卡顿了0~1秒,为何会是一个区间呢?由于你发送空消息的时候也须要考虑在内。
那若是监控一个3秒的卡顿,在第4秒的时候去检查空消息是否被消费,若是没有,说明确实发生了一个3秒以上的卡顿。
消息队列监控也存在一些问题。
好比主线程卡顿了3秒,在这3秒钟有多个函数,而经过这种方式只能获得最后一个函数的一些信息.
但实际上耗时比较久的函数不必定是最后一个.
不过对于用户量比较大的应用来讲,根据反馈回来的数据比例仍是能获得具体耗时的函数是那个。
利用lnline Hook技术和上文中提到systrace。
FaceBook开源的Profile库,性能确实很高。
可是其中黑科技太多,因此兼容性仍是个大问题。
业界都使用 Choreographer 来监控应用的帧率
监听界面是否存在绘制行为
getWindow().getDecorView().getViewTreeObserver().addOnDrawListener
复制代码
Android Vitals 将连续丢帧超过 700 毫秒定义为冻帧,也就是连续丢帧 42 帧以上。
4大组件中 Service 和 Receiver 虽然是后台组件,不过它们生命周期也是占用主线程的,调用的过于频繁也会致使卡顿.
最后,给本身公众号打个广告,【码农的唠叨】聊技术,聊热文,聊互联网趣事,也发唠叨