[轉]Android 平臺性能導致的性能案例 總結

和你一起終身學習,這裏是程序員 Android

經典好文推薦,通過閱讀本文,您將收穫以下知識點:

一、SurfaceFlinger 主線程耗時
二、屏下光感截圖導致 SurfaceFlinger 渲染不及時
三、HWC Service 執行耗時
四、CRTC 執行耗時
五、CPU 調度問題
六、觸發 Thermal 導致限頻
七、後臺活動進程太多導致系統繁忙
八、Layer過多導致 SurfaceFlinger Layer Compute 耗時
九、Input 報點不均勻
十、LMK 頻繁工作搶佔 cpu
十一 、低內存導致 IO 耗時
十二、GPU 合成導致 SurfaceFlinger 耗時
十三、KSWAPD 跑大核
十四、SurfaceFlinger Vsync 不均勻
十五、三方應用使用 Accessibility 服務導致系統卡頓

一、SurfaceFlinger 主線程耗時

SurfaceFlinger 負責 Surface 的合成 , 一旦 SurfaceFlinger 主線程調用超時 , 就會產生掉幀 .

SurfaceFlinger 主線程耗時會也會導致 hwc service 和 crtc 不能及時完成, 也會阻塞應用的 binder 調用, 如 dequeueBuffer \ queueBuffer 等.

下圖中的 SurfaceFlinger 主線程在後半部分明顯超時:

SurfaceFlinger 主線程處理不及時導致應用卡頓(第一幀卡頓,後續都爲黃幀)

二、屏下光感截圖導致 SurfaceFlinger 渲染不及時

有的 Android 機型使用了屏下光感 , 屏下光感的實現方法也會影響 SurfaceFlinger 主線程的運行 . 屏下指紋需要頻繁截圖 , 來區分光線和屏幕的變化 , 進行對應的亮度變化, 但是其主線程截圖的方法會導致 SurfaceFlinger 主線程被截圖操作所耽誤, 從而導致卡頓

三、HWC Service 執行耗時

hwc Service 耗時也會導致 SurfaceFlinger 下一幀不會做合成操作, 導致應用的 dequeueBuffer 和 setTransationState 方法被阻塞, 導致卡頓.
如下圖, 可以看到 SurfaceFlinger 的掉幀情況, Binder 的阻塞情況 和 CRTC 的耗時情況

hwc 耗時

crtc 等待 hwc

四、CRTC 執行耗時

crtc 執行耗時的結果就是 SurfaceFlinger 下一幀不會做合成操作, 導致應用的 dequeueBuffer 和 setTransationState 方法被阻塞, 導致卡頓.
如下圖, 可以看到 SurfaceFlinger 的掉幀情況, Binder 的阻塞情況 和 CRTC 的耗時情況

五、CPU 調度問題

1.重要任務跑小核性能不足導致卡頓

如下圖 , RenderThread 跑到了小核, 導致這一幀執行時間過長,造成卡頓圖片:

如下圖 , cpu 頻率對性能的影響圖片:

2.優先級低未能及時獲取 cpu 時間片導致卡頓

在調度器看來的低優先級任務 , 在用戶這裏未必是低優先級任務 , 他可能正在和 App 的主線程交互 , 或者正在和 system_server 進行交互

3. 被 RT 進程搶佔

App 主線程或者渲染線程被 RT 進程搶佔也會導致系統卡頓或者響應慢 , Google 也意識到了這個問題 , 也在嘗試在應用啓動的時候 , 把 App 主線程和渲染線程的優先級也設置爲 RT , 不過這個屬性一直沒開 , 因爲會導致應用啓動速度變慢.

4.大小核調度導致

大小核調度的問題通常表現在該跑在大核的任務跑到了小核 , 或者該在小核運行的任務卻持續跑到大核 ,或者錯誤的被綁定在了某一個核心上 .

如下圖, 這是一個 CTS 問題, CTS 主線程由於被綁定到了 cpu7 , 由於 cpu7 在執行 RenderThread , 所以主線程沒有調度到, 導致 CTS 失敗

六、觸發 Thermal 導致限頻

觸發 Thermal 發熱限頻也有可能導致卡頓 , 這算是一種硬件級別的保護 , 如果手機已經過熱 , 此時如果不進行干涉 , 那麼可能會導致用戶手機太燙而無法持續使用手機. 一般這個時候都會對系統的資源進行一些限制 , 比如降低 cpu\gpu 的最高頻率之類的 , 這麼做的話 , 勢必也會對流暢性造成影響.

如果你手機非常熱 , 而且變卡了 , 那麼放下手機休息一會 , 查殺一下後臺 , 或者重啓一下手機 .

七、 後臺活動進程太多導致系統繁忙

後臺進程活動太多,會導致系統非常繁忙, cpu \ io \ memory 等資源都會被佔用, 這時候很容易出現卡頓問題 , 這也是系統這邊經常會碰到的問題

1.CPU 繁忙

dumpsys cpuinfo 可以查看一段時間內 cpu 的使用情況

2.主線程調度不到 , 處於 Runnable 狀態

當線程爲 Runnable 狀態的時候 , 調度器如果遲遲不能對齊進行調度 , 那麼就會產生長時間的 Runnable 線程狀態 , 導致錯過 Vsync 而產生流暢性問題.

3. 無關進程活躍耗時

無關進程通常是人爲定義的 , 指的是與當前前臺 App 運行無關的進程 , 這些活躍進程勢必會對 App 主線程的調度產生影響 , 不管這些無關進程是系統的還是 App 自身的 , 或者是其他三方 App 的.

4.cpu 被佔用

原因同上 , 當後臺任務過多的時候 , cpu 資源就會異常緊缺 , 如下圖就是在系統低內存的時候 , HeapTask 和 kswapD 幾乎佔滿了整個 cpu , 在瘋狂地向系統申請內存 .

5.System 鎖

system_server 的 AMS 鎖和 WMS 鎖 , 在系統異常的情況下 , 會變得非常嚴重 , 如下圖所示 , 許多系統的關鍵任務都被阻塞 , 等待鎖的釋放 , 這時候如果有 App 發來的 Binder 請求帶鎖 , 那麼也會進入等待狀態 , 這時候 App 就會產生性能問題 ; 如果此時做 Window 動畫 , 那麼 system_server 的這些鎖也會導致窗口動畫卡頓

八、Layer過多導致 SurfaceFlinger Layer Compute 耗時

Android P 修改了 Layer 的計算方法 , 把這部分放到了 SurfaceFlinger 主線程去執行, 如果後臺 Layer 過多, 就會導致 SurfaceFlinger 在執行 rebuildLayerStacks 的時候耗時 , 導致 SurfaceFlinger 主線程執行時間過長.

所以在使用 Android 系統的時候 , 記得多用多任務清理後臺任務.

九、Input 報點不均勻

如果出現 Input 報點不均勻或者沒有報點的情況, 那麼主線程由於沒有收到 Input 事件, 所以不去做繪製, 也會導致卡頓
如下圖 , 這是一個連續滑動的 Systrace 圖 , 最下面兩行是 InputReader 和 InputDispatcher , 可以看到在滑動的過程中, InputReader 和 InputDispatcher 沒有讀出來 Input 事件, 導致卡頓

十、LMK 頻繁工作搶佔 cpu

LMK 工作時, 會佔用 cpu 資源 , 其表現主要有下面幾點

1. CPU 資源

由於 LMK 殺掉的進程通常都是一些 Cache 或者 Service , 這些進程由於低內存被殺之後 , 通常會很快就被其主進程拉起來, 然後又被 LMK 殺掉, 從而進入了一種循環. 由於起進程是一件很消耗 cpu 的操作, 所以如果後臺一直有進程被殺和重啓, 那麼前臺的進程很容易出現卡頓

2. Memory

由於低內存的原因, 很容易觸發各個進程的 GC , 如下圖的 CPU 狀態可以看到, 用於內存回收的 HeapTaskDeamon 出現非常頻繁

3. IO

低內存會導致磁盤 IO 變多, 如果頻繁進行磁盤 IO , 由於磁盤IO 很慢, 那麼主線程會有很多進程處於等 IO 的狀態, 也就是我們經常看到的 Uninterruptible Sleep

十一 、低內存導致 IO 耗時

低內存情況下, 很容易出現主線程 IO 從而導致應用卡頓

1.主線程 IO 導致卡頓

2.主線程 IO 導致應用啓動速度慢

3.滑動列表時候 IO 導致卡頓")滑動列表時候 IO 導致卡頓

十二、GPU 合成導致 SurfaceFlinger 耗時

當 SurfaceFlinger 有 GPU 合成時, 其主線程的執行時間就會變長, 也會導致合成不及時而卡頓

十三、KSWAPD 跑大核

低內存時, kswapd 由於負載比較高 , 其 cpu 佔用比較高, 且經常會跑到大核上 , 導致機器發熱限頻, 或者搶佔主線程的 cpu 時間片

十四、SurfaceFlinger Vsync 不均勻

SurfaceFlinger 有時候會出現 Vsync 不均勻的情況, 不均勻指的是 Vsync 間隔會持續地變化, 一會大一會小, 就會導致用戶看到的畫面不均勻, 有卡頓感
如下圖 , 可以明顯看到 SurfaceFlinger 的 VSYNC-sf 這一行間隔是不一樣的. 這種問題一般是由於 SurfaceFlinger 這邊的修改或者 HWC 的修改導致的 .

十五、三方應用使用 Accessibility 服務導致系統卡頓

三方應用如果使用 Accessibility 服務監聽了 Input 事件的話, InputDispatcher 的行爲就會與預期的出現偏差, 導致 InputDispatcher 沒有及時把事件傳給主線程導致卡頓

總結

Android 原生系統是一個不斷進化的過程 , 目前已經進化到了 Android Q , 每個版本都會解決非常多的性能問題 , 同時也會引進一些問題 ; 到了手機廠商這裏 , 由於硬件差異和軟件定製 , 會在系統中加入大量的自己的代碼 , 這無疑也會影響系統的性能 .

上面列出的這些影響流暢性的案例 , 只是 Android 系統開發中遇到的性能問題的冰山一角 , 任何一個問題都會對用戶的使用產生影響 , 這也是爲什麼手機廠商越來越重視系統優化 . 手機廠商非常重視開發過程中和用戶使用過程中遇到的性能問題 , 並開發和提出各項優化措施 , 從硬件到軟件 , 從用戶行爲優化到系統策略動態學習 . 這也是爲什麼現在的手機廠商的系統越做越好 , 質量越來越高的一個原因 , 那些不重視質量只重視設計和產品的手機廠商 , 都漸漸地被消費者淘汰了.

原文鏈接:https://www.androidperformance.com/2019/09/05/Android-Jank-Due-To-System/

至此,本篇已結束。轉載網絡的文章,小編覺得很優秀,歡迎點擊閱讀原文,支持原創作者,如有侵權,懇請聯繫小編刪除,歡迎您的建議與指正。同時期待您的關注,感謝您的閱讀,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章