讀書筆記3-卡頓優化篇

本系列博文 基因而前微信高級工程師張紹文專欄 《Android開發高手課》的讀書筆記。java

文章所寫內容是本人讀完的感悟,須要原文的朋友請自行購買。性能優化

卡頓優化篇

先貼兩篇比較簡單的分析文章bash

Android性能優化-界面渲染原理淺析微信

Android界面渲染優化函數

下面進入正題工具

卡頓根本緣由

形成卡頓的緣由可能有千百種,不過最終都會反映到CPU 時間上.oop

CPU時間分兩種性能

  • 用戶時間 執行用戶態應用程序代碼所消耗的時間
  • **系統時間 **執行內核態系統調用所消耗的時間,包括 I/O、鎖、中斷以及其餘系統調用時間

CPU使用狀態有如下幾個指標優化

  • CPU 使用率: 若是 CPU 使用率長期大於 60% ,表示系統處於繁忙狀態,就須要進一步分析用戶時間和系統時間的比例。對於普通應用程序,系統時間不會長期高於 30%,若是超過這個值,就得考慮是否I/O調用過多或者鎖調用的過於頻繁的問題。(Android studio 3.0的版本以後能夠直接觀測到CPU的使用狀況)spa

  • 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
相關文章
相關標籤/搜索