中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android中如何優化卡頓

發布時間:2021-06-29 16:09:19 來源:億速云 閱讀:110 作者:Leah 欄目:移動開發

本篇文章為大家展示了Android中如何優化卡頓,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

  1. CPU 性能
    在開發過程中,我們可以通過下面的方法獲得設備的 CPU 信息。
    // 獲取 CPU 核心數
    cat /sys/devices/system/cpu/possible

    // 獲取某個 CPU 的頻率
    cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq

  2. 卡頓問題分析指標
    出現卡頓問題后,首先我們應該查看CPU 的使用率。怎么查呢?我們可以通過/proc/stat
    得到整個系統的 CPU 使用情況,通過/proc/[pid]/stat
    可以得到某個進程的 CPU 使用情況。
    關于 stat 文件各個屬性的含義和 CPU 使用率的計算,你可以閱讀《Linux 環境下進程的 CPU 占用率》和Linux 文檔。其中比較重要的字段有:
    proc/self/stat:
    utime:       用戶時間,反應用戶代碼執行的耗時  
    stime:       系統時間,反應系統調用執行的耗時
    majorFaults:需要硬盤拷貝的缺頁次數
    minorFaults:無需硬盤拷貝的缺頁次數

如果 CPU 使用率長期大于 60% ,表示系統處于繁忙狀態,就需要進一步分析用戶時間和系統時間的比例。對于普通應用程序,系統時間不會長期高于 30%,如果超過這個值,我們就應該進一步檢查是 I/O 過多,還是其他的系統調用問題。
Android 是站在 Linux 巨人的肩膀上,雖然做了不少修改也砍掉了一些工具,但還是保留了很多有用的工具可以協助我們更容易地排查問題,這里我給你介紹幾個常用的命令。例如,top 命令可以幫助我們查看哪個進程是 CPU 的消耗大戶;vmstat 命令可以實時動態監視操作系統的虛擬內存和 CPU 活動;strace 命令可以跟蹤某個進程中所有的系統調用。
除了 CPU 的使用率,我們還需要查看CPU 飽和度。CPU 飽和度反映的是線程排隊等待 CPU 的情況,也就是 CPU 的負載情況。
CPU 飽和度首先會跟應用的線程數有關,如果啟動的線程過多,容易導致系統不斷地切換執行的線程,把大量的時間浪費在上下文切換,我們知道每一次 CPU 上下文切換都需要刷新寄存器和計數器,至少需要幾十納秒的時間。
我們可以通過使用vmstat
命令或者/proc/[pid]/schedstat
文件來查看 CPU 上下文切換次數,這里特別需要注意nr_involuntary_switches
被動切換的次數。
proc/self/sched:
nr_voluntary_switches:    
主動上下文切換次數,因為線程無法獲取所需資源導致上下文切換,最普遍的是 IO。    
nr_involuntary_switches:  
被動上下文切換次數,線程被系統強制調度導致上下文切換,例如大量線程在搶占 CPU。
se.statistics.iowait_count:IO 等待的次數
se.statistics.iowait_sum:  IO 等待的時間

此外也可以通過 uptime 命令可以檢查 CPU 在 1 分鐘、5 分鐘和 15 分鐘內的平均負載。比如一個 4 核的 CPU,如果當前平均負載是 8,這意味著每個 CPU 上有一個線程在運行,還有一個線程在等待。一般平均負載建議控制在“0.7 × 核數”以內。
00:02:39 up 7 days, 46 min,  0 users,  
load average: 13.91, 14.70, 14.32

另外一個會影響 CPU 飽和度的是線程優先級,線程優先級會影響 Android 系統的調度策略,它主要由 nice 和 cgroup 類型共同決定。nice 值越低,搶占 CPU 時間片的能力越強。當 CPU 空閑時,線程的優先級對執行效率的影響并不會特別明顯,但在 CPU 繁忙的時候,線程調度會對執行效率有非常大的影響。
關于線程優先級,你需要注意是否存在高優先級的線程空等低優先級線程,例如主線程等待某個后臺線程的鎖。從應用程序的角度來看,無論是用戶時間、系統時間,還是等待 CPU 的調度,都是程序運行花費的時間。
Android 卡頓排查工具
Traceview 和 systrace 都是我們比較熟悉的排查卡頓的工具,從實現上這些工具分為兩個流派。
第一個流派是 instrument。獲取一段時間內所有函數的調用過程,可以通過分析這段時間內的函數調用流程,再進一步分析待優化的點。
第二個流派是 sample。有選擇性或者采用抽樣的方式觀察某些函數調用過程,可以通過這些有限的信息推測出流程中的可疑點,然后再繼續細化分析。
這兩種流派有什么差異?我們在什么場景應該選擇哪種合適的工具呢?還有沒有其他有用的工具可以使用呢?下面我們一一來看。

  1. Traceview
    Traceview是我第一個使用的性能分析工具,也是吐槽的比較多的工具。它利用 Android Runtime 函數調用的 event 事件,將函數運行的耗時和調用關系寫入 trace 文件中。
    由此可見,Traceview 屬于 instrument 類型,它可以用來查看整個過程有哪些函數調用,但是工具本身帶來的性能開銷過大,有時無法反映真實的情況。比如一個函數本身的耗時是 1 秒,開啟 Traceview 后可能會變成 5 秒,而且這些函數的耗時變化并不是成比例放大。
    在 Android 5.0 之后,新增了startMethodTracingSampling
    方法,可以使用基于樣本的方式進行分析,以減少分析對運行時的性能影響。新增了 sample 類型后,就需要我們在開銷和信息豐富度之間做好權衡。

無論是哪種的 Traceview 對 release 包支持的都不太好,例如無法反混淆。其實 trace 文件的格式十分簡單,之前曾經寫個一個小工具,支持通過 mapping 文件反混淆 trace。

  1. systrace
    systrace是 Android 4.1 新增的性能分析工具。我通常使用 systrace 跟蹤系統的 I/O 操作、CPU 負載、Surface 渲染、GC 等事件。
    systrace 利用了 Linux 的ftrace調試工具,相當于在系統各個關鍵位置都添加了一些性能探針,也就是在代碼里加了一些性能監控的埋點。Android 在 ftrace 的基礎上封裝了atrace,并增加了更多特有的探針,例如 Graphics、Activity Manager、Dalvik VM、System Server 等。
    systrace 工具只能監控特定系統調用的耗時情況,所以它是屬于 sample 類型,而且性能開銷非常低。但是它不支持應用程序代碼的耗時分析,所以在使用時有一些局限性。
    由于系統預留了Trace.beginSection
    接口來監聽應用程序的調用耗時,那我們有沒有辦法在 systrace 上面自動增加應用程序的耗時分析呢?
    劃重點了,我們可以通過編譯時給每個函數插樁的方式來實現,也就是在重要函數的入口和出口分別增加Trace.beginSection
    和Trace.endSection
    。當然出于性能的考慮,我們會過濾大部分指令數比較少的函數,這樣就實現了在 systrace 基礎上增加應用程序耗時的監控。通過這樣方式的好處有:
    ?   可以看到整個流程系統和應用程序的調用流程。包括系統關鍵線程的函數調用,例如渲染耗時、線程鎖,GC 耗時等。
    ?   性能損耗可以接受。由于過濾了大部分的短函數,而且沒有放大 I/O,所以整個運行耗時不到原來的兩倍,基本可以反映真實情況。
    systrace 生成的是 HTML 格式的結果。

目前兩個工具都只支持 debugable 的應用程序,如果想測試 release 包,需要將測試機器 root。對于這個限制,我們在實踐中會專門打出 debugable 的測試包,然后自己實現針對 mapping 的反混淆功能。

隨著 Android 版本的演進,Google 不僅提供了更多的性能分析工具,而且也在慢慢優化現有工具的體驗,使功能更強大、使用門檻更低。而 Android Studio 則肩負另外一個重任,那就是讓開發者使用起來更加簡單的,圖形界面也更加直觀。
在 Android Studio 3.2 的 Profiler 中直接集成了幾種性能分析工具,其中:
?   Sample Java Methods 的功能類似于 Traceview 的 sample 類型。
?   Trace Java Methods 的功能類似于 Traceview 的 instrument 類型。
?   Trace System Calls 的功能類似于 systrace。
?   SampleNative (API Level 26+) 的功能類似于 Simpleperf。
坦白來說,Profiler 界面在某些方面不如這些工具自帶的界面,支持配置的參數也不如命令行,不過 Profiler 的確大大降低了開發者的使用門檻。
另外一個比較大的變化是分析結果的展示方式,這些分析工具都支持了 Call Chart 和 Flame Chart 兩種展示方式。下面我來講講這兩種展示方式適合的場景。

  1. Call Chart
    Call Chart 是 Traceview 和 systrace 默認使用的展示方式。它按照應用程序的函數執行順序來展示,適合用于分析整個流程的調用。舉一個最簡單的例子,A 函數調用 B 函數,B 函數調用 C 函數,循環三次,就得到了下面的 Call Chart。

Call Chart 就像給應用程序做一個心電圖,我們可以看到在這一段時間內,各個線程的具體工作,比如是否存在線程間的鎖、主線程是否存在長時間的 I/O 操作、是否存在空閑等。

  1. Flame Chart
    Flame Chart 也就是大名鼎鼎的火焰圖。它跟 Call Chart 不同的是,Flame Chart 以一個全局的視野來看待一段時間的調用分布,它就像給應用程序拍 X 光片,可以很自然地把時間和空間兩個維度上的信息融合在一張圖上。上面函數調用的例子,換成火焰圖的展示結果如下。

當我們不想知道應用程序的整個調用流程,只想直觀看出哪些代碼路徑花費的 CPU 時間較多時,火焰圖就是一個非常好的選擇。例如,之前我的一個反序列化實現非常耗時,通過火焰圖發現耗時最多的是大量 Java 字符串的創建和拷貝,通過將核心實現轉為 Native,最終使性能提升了很多倍。

上述內容就是Android中如何優化卡頓,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

甘肃省| 丽水市| 石泉县| 双鸭山市| 芜湖市| 新沂市| 海伦市| 武强县| 新河县| 砚山县| 兴义市| 长丰县| 九龙县| 贵溪市| 布尔津县| 自贡市| 武宁县| 沐川县| 定兴县| 临沂市| 陵水| 敦化市| 九寨沟县| 望都县| 舒兰市| 宜都市| 邵阳市| 达孜县| 大姚县| 芒康县| 安宁市| 德保县| 济源市| 阿鲁科尔沁旗| 大余县| 竹山县| 霞浦县| 朝阳县| 重庆市| 东至县| 壤塘县|