關於 Android 系統流暢性的一些思考
來自專欄 Android Tips90 人贊了文章
本文首發:
http://www.androidperformance.com/2018/08/13/Some-Thoughts-on-the-Fluency-of-Android/最近一直想寫一些關於 Android 系統流暢度的東西,因為流暢度這個東西,是消費者最直接能體驗到的,再加上 Android 一直為人詬病的越用越卡頓,使得大家在提到安卓機的時候,都會有一絲陰影。這也是大部分人買手機首先會考慮 iPhone 的一個原因。
由於 Google 對 Android 持開放態度,各個手機廠商生產不同產品定位的機器,以及各個 Android 應用的質量良莠不齊,導致影響 Android 流暢度的因素非常非常多,並非大家簡單的以為是系統沒有優化好,很多時候你會發現,不同 SOC 但是相同的系統,體驗完全就是兩種。
所以我想和大家聊聊影響 Android 系統流暢性的一些原因,後續大家遇到卡頓的問題,也不會單純把鍋甩給系統,或許你卸載一個 App 就解決了呢.
我想從下面幾個方面展開聊這個話題
- 硬體層面
- 系統層面
- 應用層面
- 流暢度優化閉環
準備好了,那就開始吧,歡迎你加入討論
1. 硬體層面
CPU
cpu 是手機硬體裡面最核心的一個器件,這也是把 cpu 作為第一個來說的主要原因,cpu 之所以重要,是因為 Android 系統的運行過程中,大部分是跟 cpu 打交道,cpu 的能力強弱,直接決定了這款手機的檔次。
手機 cpu 目前主要有高通、華為、三星、聯發科四家在做,每家都有高中低檔,高端 cpu 的排名大概是 高通>華為>三星>聯發科,再具體點就是高通845>華為970>三星9810>聯發科X30. 具體的排名可以去這裡看:http://www.mydrivers.com/zhuanti/tianti/01/
GPU
各個廠商提供的 SOC 裡面,通常包含了 cpu 和 gpu ,所以大部分情況下,只要一說 cpu,其 gpu 也是對應確定的,比如高通驍龍845 SOC 帶的 gpu 就是 Adreno 630。
gpu 的能力強弱更多的影響的是 gpu 強相關的應用和遊戲,比如絕地求生-刺激戰場 、 崩壞3 、極品飛車、狂野飆車等。反而王者榮耀這樣的遊戲更多的是吃 cpu 而不是 gpu。
Ram
隨著 Android 版本的更新,以及硬體的更新換代,Android 系統對內存的需求越來越強,目前4G內存的手機基本上已經成了標配,旗艦機器沒個 6G 或者 8G 你都不好意思說自己是旗艦。
內存主要影響系統行為,內存越大,系統就越可以以空間換時間:後台可以緩存更多的進程,殺進程不再那麼激進;可以根據用戶習慣預載入一些文件或者進程;各種虛擬機、hwui、進程的參數可以往寬鬆里調。反饋到用戶那裡,就是快。
當然如果後台進程多了又沒有管住在後台跑,那麼又會很耗電,有點得不償失,這也是為什麼國內的系統都會對進程管理這一塊進行魔改。
UFS && EMMC
ufs 和 emmc 都是面向移動端的 flash 標準,我們最長聽說的就是 emmc5.1 和 ufs 2.1 ,具體可以參考這篇文章:https://zhuanlan.zhihu.com/p/26431201
對於用戶來說,ufs 和 emmc 的差異主要在文件讀取速度、視頻載入速度、文件拷貝等方面,總之能上ufs就別考慮 emmc。
不過有時候這個也是需要 SOC 支持的,比如高通 660,就不支持 ufs,能不買就別買吧。
屏幕解析度
我們最常見的屏幕解析度是 1080P,即 1920*1080. 對用戶來說,屏幕解析度除了會影響視覺感官外,還會在系統某些地方有差異,比如截圖、錄屏、合成等操作。越高的屏幕解析度,在這裡的耗時就越久,也越耗電。
這也是部分 2K 手機在某些場景下,把解析度降低到 1080P 去運行的原因。比較失敗的一個例子就是當年的魅族 MX4 Pro ,在硬體性能不足以支撐 2K 的情況下,強行上了 2K 屏幕,導致很多情況下,用戶反饋又卡又耗電。
電池大小
電池大小決定著續航,也決定著手機設計,手機廠家往往需要在這兩者之間找一個平衡,在電池技術沒有突破的情況下,就算各家都有快充,還是建議用戶在選購手機的時候,盡量選大容量電池的手機,比如 Oppo Find X 或者 Vivo NEX,或者華為 Mate 10.
SoC 平台
SoC的全稱叫做:System-on-a-Chip,除了我們之前說的 cpu、gpu,Soc 上還有很多器件,具體可以看這篇文章:https://zhuanlan.zhihu.com/p/37634251 ,這裡就不展開講了。
SoC 是整個手機最重要的部分,是一切體驗的基礎。現在高通、三星、MTK 給手機廠家提供的硬體就是 Soc ,以及其配套的 Android 適配系統。手機廠商拿到這個之後,在其基礎上做整機的設計,系統這邊會在配套的 Android 適配系統上做移植,也就是把各家系統差異化的東西移植到新系統上。
從目前的高通、三星、MTK 三家的適配系統的質量來看,高通提供的適配系統是功能最完善的,高通在 AOSP 的基礎上,加上了高通自己的非常多的優化代碼,並提供了完善的參數供手機廠商去配置,總的來說開發起來是很舒服的,本身系統的問題不會太多,加上高通的文檔完善,支持速度快,國內那麼多手機廠商都在用高通也就不足為奇了。
至於專利費,該給的要給啊。
我們經常會說,如果魅族早點用高通的 Soc,早 TM 上市了。
2. 系統層面
應用的管控策略
大部分 Android 應用開發者對國內的手機廠商恨的咬牙切齒,最大的原因就是國內系統對應用管控這一塊進行了大量的魔改,除非你是 QQ 或者微信,否則滅了屏結果都一樣。
國內廠商這麼做,不是沒有原因的,國內應用廠商的全家桶相互喚醒,已經到了一種喪心病狂的地步,牽一髮而動全身,一點都不誇張。
我們遇到的很多用戶反饋的整機卡頓問題,抓 Trace 和 Log 來看,都是後台有應用在亂跑,或者後台大量的進程常駐,內存根本不夠,而這些普通用戶根本就不知道怎麼去處理。
所以國內廠商一般會在系統裡面做限制,以保障用戶的基礎體驗:
- 除非必須,一個應用偷偷拉起來另外一個應用的行為是不被允許的
- 除非必須,一個應用常駐後台是不被允許的
- 除非必須,一個應用在滅屏後在後台亂跑是不被允許的
- 除非必須,一個應用在後台長時間佔用 cpu 是不被允許的
- 除非必須,一個應用彈窗是不被允許的
另外手機廠商會有其他的邏輯清理後台的應用,儘管你是合理存在的。
對進程的嚴格管控,也導致了國內系統的體驗有一定的影響,首當其衝的是通知,如果一個應用沒有接入這個手機廠商提供的 push sdk,那麼他這輩子別想發通知給用戶了,如果接入了手機廠商提供的 sdk(目前大部分應用的普遍做法),由於應用不在後台,用戶點擊通知要等好久才可以進入到對應的界面,毫無用戶體驗可言。
內存策略
手機廠商常常會根據手機的內存大小來定製各種不同的策略,比如後台應用的緩存個數、LowMemoryKiller 的閾值、殺進程模塊的閾值、顯示模塊的緩存大小閾值、用戶最常用應用的個數等。
很多低端機用戶反饋卡頓,我們查看發現,內存是造成卡頓的主要元兇,在低內存的機器上,由於內存不足,系統會頻繁殺後台,同時也有頻繁的內存->文件,文件->內存 的操作,Trace 上很多 BlockIO,很多平時執行很快的操作,現在執行要很久,再加上部分進程被殺之後馬上重啟,重啟之後又被殺,cpu 佔用很高,此時就會很卡。
隨著 Android 系統和應用的更新,只會越來越吃內存,目前4G內存是標配,明年或許 6G 才是標配了,能上 8G 盡量上 8G。
進程調度策略
進程調度策略有時候也會影響用戶的流暢性,當應用的渲染鏈路上,有哪個環節因為某些原因,沒有被調度到的時候,很大可能會造成卡頓。
調度不到在 Trace 上的表現是 Runnable,常見的調度不到的情況有:
- 同時運行的進程太多,cpu 這邊的幾個核處理的任務基本都是滿的
- 進程優先順序較低
- 調度器過於不靈敏,不能及時響應大任務
另外由於 cpu 引起的卡頓情況還有:
- 從大核心掉落到小核心上,小核心處理能力不足,會造成短暫的卡頓
- 觸發溫控或者觸發低電量,此時某些系統會限制大核的使用,導致卡頓
- 系統鎖也是造成卡頓的一大元兇,尤其是 wms 鎖和 ams 鎖,再加上 binder 通信,relayoutWindow 了解一下?
- 核心頻率不足,導致函數執行時間過長導致卡頓
- 大核心被佔用,任務又調度不到小核,導致卡頓
系統調優往往需要針對上面的情況做對應的處理,給用戶一個好的用戶體驗。具體的調優方式,往往跟系統和 Soc 強相關,又涉及到 Kernel 和 功耗,改起來是牽一髮而動全身,需要非常謹慎。
渲染線程和主線程
Android 應用的渲染鏈路上最重要的就是主線程和渲染線程,主線程就是應用啟動時創建的 MainThread,對應的也會創建一個 RenderThread(硬體加速默認開啟),我們平時比較看重的 GPU Profile 那條線,基本就包含了主線程和渲染線程的各個階段的執行時間,從 GPU Profile ,就可以很容易看到應用的瓶頸
大部分應用的卡頓都發生在主線程和渲染線程上,比如:
- 較長時間的 input 事件處理
- 較長時間的動畫事件處理,比如 ListView 的新 Item 的生成
- 複雜界面的 Measure、 Layout、Draw
- 較大 Bitmap 的頻繁 upload
- 複雜渲染指令的執行
很多編程的不好的實現,都可以在上面幾個步驟裡面體現出來,這些都可以通過 Systrace 看出來。
當前應用的渲染鏈路上的一切優先順序都應該是最高的,後台的進程不應該對其造成影響,這也是系統優化的核心要素,不過要做到這一點也是比較難的,你很難考慮到所有的情況,比如有的用戶的使用環境就是很複雜,而且都是必須的,這時候就不是很好處理。
TripleBuffer
之前有提到 TripleBuffer,這個是 Project Butter 引進的,其中 Vsyncv 和 TripleBuffer 的引進使得 Android 的流暢度上了一個台階,關於這個可以參考這篇文章 : https://niorgai.github.io/2017/03/21/Android-Draw-System/
對於用戶來說這個是透明的,影響的是 GPU Profile 的展示,有時候如果有一條線超過 16 ms 的警戒線,它不一定代表著卡頓,這就是 TrileBuffer 的作用。
後續我會有文章專門講這個,如何判斷是真正的卡頓。
虛擬機 - Art 和 Dalvik
對用戶來說,Art 虛擬機相比 Dalvik 虛擬機,最大的提升就是解放了應用的主線程,主線程不再頻繁被 GC 線程 Stop ,相應卡頓也減少了很多。
當然 Art 帶來的好處不止這一點,Art 隨著幾個大版本的縫縫補補,已經在很多地方遠遠超過了 Dalvik,有興趣的可以自己查一下。
溫控 && 低電量
之前提到,一旦觸發溫控或者低電量,系統會對資源做一定的限制,防止手機無限制過熱或者快速關機。這限制就包括
- 降低 cpu、gpu 最高頻率
- 減少可運行的 cpu 的核心數
- 殺掉部分後台進程
- 關閉部分特效
- 限制網路連接
總之,這些限制或多或少會對用戶造成影響,最大的影響就是卡頓,這就是很多人會遇到打遊戲的時候突然很卡的一個原因。
所以說選購手機的時候,除了要看 Soc,還要看散熱是否做的夠好,電池是否做的夠大。
3. 應用層面
複雜的布局
複雜的布局往往是應用卡頓的最主要的元兇之一,複雜的布局意味著更長的 Measure、Layout、Draw ,這會拖慢主線程的執行速度
ListView、RecyclerView 的新的 Item 在初始化的時候也會有類似的問題,由於此時一般是在滑動,這時候的卡頓感會更明顯,用戶也更容易察覺,這個從 Trace 上也很容易看出來。
過多的業務邏輯
過多業務邏輯導致的卡頓和響應慢的問題,拿淘寶來舉例子最合適不過了,每次你冷啟動淘寶的時候,進入主界面馬上滑動,總感覺跟吃了屎一樣,點按鈕點不動,滑界面滑不動,雖然最近的版本有優化,不過你找個低端 Android 機,還是原來的配方。
淘寶在啟動的時候,需要動態載入很多東西,導致主界面響應很慢,很多東西要動態載入完成後才可以操作,後台還有大量的 dex2oat 操作,可以說是很忙了。
內存顛簸
頻繁申請和釋放內存,會導致內存顛簸,從 AS 的內存監視器可以看到這一點,短時間內內存曲線上下跳動非常頻繁,這時候你需要檢查一下是否代碼寫的有問題。
慢網路
慢網路指的是用戶請求網路耗時很久,這會導致用戶在某些界面等待內容需要很久,比如知乎經常會出現這種情況,在用戶看來,這就是卡了。
不合理的設計
設計和性能往往不可兼得,需要從兩者之間做取捨,設計師的設計往往很炫酷,互相嵌套的動畫往往是程序員的噩夢,為了實現這些複雜的效果,程序員往往需要複雜的代碼來實現,這對應用的渲染鏈路的壓力是非常大的,而且在不同性能的機器上表現差異很大,高端機用戶覺得這個效果棒棒噠,低端機用戶卡的要罵娘。
程序員需要有這方面的知識和數據,好與設計師動之以情曉之以理。
不過用戶是很挑剔的,現在的用戶對性能的要求越來越高,哪怕是低端機用戶,所以合適的設計應該考慮到這部分用戶、或者針對低端機用戶做區分。
代碼實現錯誤
俗稱 bug ,很多程序員不喜歡解決性能問題,因為這個東西解決起來,性價比很低,拿我司的程序員來說,解一個性能問題的時間,可以解決十幾個界面顯示的問題,還未必能真的解決。
不過由於代碼實現錯誤引起的性能問題,必須要最高優先順序解決。
4. 流暢度優化閉環
實驗室監控 && 模擬用戶
開發階段就用各項數據來做監控和對比,盡量模擬用戶的使用環境,儘早暴漏性能問題,早日解決。
用戶流暢度數據收集
在用戶使用階段,收集性能數據,針對這些數據做分析,找出用戶最多遇到的性能問題,針對性地做優化。需要注意此時不能在用戶階段手機太多的信息,否則會導致觀察者效應
至於需要收集的數據,則需要根據相關度模型來做判斷,卡頓發生的時候,系統的哪些指標是可能導致卡頓的原因,那麼這些指標就是我們收集的數據。
另外用戶的場景判斷也非常重要,需要知道用戶是在哪個場景出現的卡頓,一旦用戶的數量到了一定的級別,這個是很容易發現問題的。
針對性地優化
大數據發現問題後,後續就是針對性地進行優化,把用戶最常遇到性能問題的場景進行排序,對最常見的場景進行調研和優化。很多時候需要與應用開發廠商進行溝通,
然後需要把這些場景納入到實驗室監控環境里,做到 實驗室監控 —> 模擬用戶 — > 大數據收集 —> 針對性優化 —> 實驗室監控補充. 這樣一個閉環。
推薦閱讀: