本系列博文 基因而前微信高級工程師張紹文專欄 《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 雖然是後臺組件,不過它們生命週期也是佔用主線程的,調用的過於頻繁也會致使卡頓.
最後,給本身公衆號打個廣告,【碼農的嘮叨】聊技術,聊熱文,聊互聯網趣事,也發嘮叨