深入理解Android Runtime

image.png

上圖是Android整體的架構(gòu)障般,Android Runtime之于Android而言相當(dāng)于心臟之于人體盛杰,是Android程序加載和運(yùn)行的環(huán)境即供。這篇文章主要針對Android Runtime部分進(jìn)行展開,探討Android Runtime的發(fā)展以及目前現(xiàn)狀办素,并介紹應(yīng)用Profile-Guided Optimization(PGO)技術(shù)對應(yīng)用啟動(dòng)速度進(jìn)行優(yōu)化的可行性性穿。轉(zhuǎn)載請注明來源「申國駿」

App運(yùn)行時(shí)演進(jìn)

JVM

Android原生代碼使用Java或者Kotlin編寫雷滚,這些代碼會(huì)通過javac或者kotlinc編譯成.class文件祈远,在Android之前车份,這些.class文件會(huì)被輸入到JVM中執(zhí)行。JVM可以簡單分為三個(gè)子系統(tǒng)出爹,分別是Class Loader严就、Runtime Data Area以及Execution Engine梢为。其中Class Loader主要負(fù)責(zé)加載類、校驗(yàn)字節(jié)碼祟印、符號引用鏈接及對靜態(tài)變量和靜態(tài)方法分配內(nèi)存并初始化旁理。Runtime Data負(fù)責(zé)存儲(chǔ)數(shù)據(jù)我磁,分為方法區(qū)夺艰、堆區(qū)郁副、棧區(qū)存谎、程序計(jì)數(shù)器以及本地方法棧肥隆。Execution Engine負(fù)責(zé)二進(jìn)制代碼的執(zhí)行以及垃圾回收栋艳。

image.png

Execution Engine中吸占,會(huì)采用Interpreter或者JIT執(zhí)行矾屯。其中Interpreter表示在運(yùn)行的過程中對二進(jìn)制代碼進(jìn)行解釋,每次執(zhí)行相同的二進(jìn)制代碼都進(jìn)行解釋比較浪費(fèi)資源孙技,因此對于熱區(qū)的二進(jìn)制代碼會(huì)進(jìn)行JIT即時(shí)編譯绪杏,對二進(jìn)制代碼編譯成機(jī)器碼纽绍,這樣相同的二進(jìn)制代碼執(zhí)行時(shí)拌夏,就不用再次進(jìn)行解釋履因。

image.png

DVM(Android 2.1/2.2)

JVM是stack-based的運(yùn)行環(huán)境栅迄,在移動(dòng)設(shè)備中對性能和存儲(chǔ)空間要求較高毅舆,因此Android使用了register-based的Dalvik VM憋活。從JVM轉(zhuǎn)換到DVM我們需要將.class文件轉(zhuǎn)換為.dex文件虱黄,從.class轉(zhuǎn)換到.dex的過程需要經(jīng)過 desugar -> proguard -> dex compiler三個(gè)過程橱乱,這三個(gè)過程后來逐步變成 proguard -> D8(Desugar) 直到演變到今天只需要一步R8(D8(Desugar))。

image.png

我們主要關(guān)注Android中Runtime Engine與JVM的區(qū)別作瞄。在Android早期的版本里面,只存在Interpreter解釋器粉洼,到了Android2.2版本將JIT引入属韧,這個(gè)版本Dalvik與JVM的Runtime Engine區(qū)別不大宵喂。

image.png

ART-AOT(Android 4.4/5.0)

為了加快應(yīng)用的啟動(dòng)速度和體驗(yàn)锅棕,到了Android4.4淌山,Google提供了一個(gè)新的運(yùn)行時(shí)環(huán)境ART(Android Runtime)泼疑,到了Android5.0,ART替換Dalvik成為唯一的運(yùn)行時(shí)環(huán)境移稳。

image.png

ART運(yùn)行時(shí)環(huán)境中个粱,采用了AOT(Ahead-of-time)編譯方式都许,即在應(yīng)用安裝的時(shí)候就將.dex提前編譯成機(jī)器碼,經(jīng)過AOT編譯之后.dex文件會(huì)生成.oat文件颖低。這樣在應(yīng)用啟動(dòng)執(zhí)行的時(shí)候,因?yàn)椴恍枰M(jìn)行解釋編譯蹬敲,大大加快了啟動(dòng)速度伴嗡。

image.png

然而AOT帶來了以下兩個(gè)問題:

  1. 應(yīng)用安裝時(shí)間大幅增加瘪校,由于在安裝的過程中同時(shí)需要編譯成機(jī)器碼,應(yīng)用安裝時(shí)間會(huì)比較長泣懊,特別在系統(tǒng)升級的時(shí)候馍刮,需要對所有應(yīng)用進(jìn)行重新編譯窃蹋,出現(xiàn)了經(jīng)典的升級等待噩夢警没。
image.png
  1. 應(yīng)用占用過多的存儲(chǔ)空間,由于所有應(yīng)用都被編譯成.oat機(jī)器碼亡脸,應(yīng)用所占的存儲(chǔ)空間大大增加梗掰,使得本來并不充裕的存儲(chǔ)空間變得雪上加霜。

進(jìn)一步思考對應(yīng)用全量進(jìn)行編譯可能是沒有必要的摧茴,因?yàn)橛脩艨赡苤粫?huì)用到一個(gè)應(yīng)用的部分常用功能苛白,并且全量編譯之后更大的機(jī)器碼加載會(huì)占用IO資源焚虱。

ART-PGO(Android 7.0)

從Android7.0開始鹃栽,Google重新引入了JIT的編譯方式民鼓,不再對應(yīng)用進(jìn)行全量編譯,結(jié)合AOT夯到、JIT耍贾、Interpreter三者的優(yōu)勢提出了PGO(Profile-guided optimization)的編譯方式荐开。

在應(yīng)用執(zhí)行的過程中劝赔,先使用Interpreter直接解釋着帽,當(dāng)某些二進(jìn)制代碼被調(diào)用次數(shù)較多時(shí)仍翰,會(huì)生成一個(gè)Profile文件記錄這些方法存儲(chǔ)起來予借,當(dāng)二進(jìn)制代碼被頻繁調(diào)用時(shí)频蛔,則直接進(jìn)行JIT即時(shí)編譯并緩存起來晦溪。

當(dāng)應(yīng)用處于空閑(屏幕關(guān)閉且充電)的狀態(tài)時(shí)三圆,編譯守護(hù)進(jìn)程會(huì)根據(jù)Profile文件進(jìn)行AOT編譯舟肉。

當(dāng)應(yīng)用重新打開時(shí),進(jìn)行過JIT和AOT編譯的代碼可以直接執(zhí)行查库。

這樣就可以在應(yīng)用安裝速度以及應(yīng)用打開速度之間取得平衡路媚。

image.png
image.png

JIT 工作流程:

image.png

ART-Cloud Profile(Android 9.0)

不過這里還是有一個(gè)問題,就是當(dāng)用戶第一次安裝應(yīng)用的時(shí)候并沒有進(jìn)行任何的AOT優(yōu)化樊销,通常會(huì)經(jīng)過用戶多次的使用才能使得啟動(dòng)速度得到優(yōu)化整慎。

image.png

考慮到一個(gè)應(yīng)用通常會(huì)有一些用戶經(jīng)常使用執(zhí)行的代碼(例如啟動(dòng)部分以及用戶常用功能)并且大多數(shù)時(shí)候會(huì)有先行版本用于收集Profile數(shù)據(jù),因此Google考慮將用戶生成的Profile文件上傳到Google Play中现柠,并在應(yīng)用安裝時(shí)同時(shí)帶上這個(gè)Profile文件院领,在安裝的過程中,會(huì)根據(jù)這個(gè)Profile對應(yīng)用進(jìn)行部分的AOT編譯够吩。這樣當(dāng)用戶安裝完第一次打開的時(shí)候周循,就能達(dá)到較快的啟動(dòng)速度。

image.png
image.png

Profile in cloude 需要系統(tǒng)應(yīng)用市場支持,在國內(nèi)市場使用Google Play的占比非常低临扮,因此cloud profile的優(yōu)化在國內(nèi)幾乎是沒有作用的,不過Profile的機(jī)制提供了一個(gè)可以做啟動(dòng)優(yōu)化的思路蚜退。早在2019年蚂且,支付寶就在秒開技術(shù)的回應(yīng)的里面提到過profile-based compile的技術(shù)杏死,參考:如何看待今日頭條自媒體發(fā)布謠言稱「支付寶幾乎秒開是因?yàn)椴捎萌A為方舟編譯器」?窒舟,這也是我們一直研究Profile技術(shù)的原因。困擾著我們的一直有兩個(gè)問題洁墙,第一個(gè)問題是如何生成Profile文件,第二個(gè)問題是怎么使用生成的Profile文件孝扛。對于第一個(gè)問題的解決相對還是有思路的,因?yàn)閍pp運(yùn)行就會(huì)生成profile文件陌选,因此我們手動(dòng)運(yùn)行幾次app就能在文件系統(tǒng)中收集到這個(gè)文件,不過如何以一種較為自動(dòng)化的手段收集仍然是個(gè)問題臼勉。第二個(gè)問題我們知道Profile文件最終生成的位置囱晴,因此我們可以把生成的文件放到相應(yīng)的系統(tǒng)目錄畸写,不過大多數(shù)手機(jī)和應(yīng)用都沒有權(quán)限直接放置這個(gè)文件。因此Profile優(yōu)化技術(shù)一直都沒有落地千所,直到Baseline Proflie讓我們看到了希望。

Baseline Profile

Baseline Profile是一套生成和使用Profile文件的工具待错,在2022年一月份開始進(jìn)入視野,隨后在Google I/O 2022隨著Jetpack新變化得到廣泛關(guān)注瓜客。其背景是Google Map加快了發(fā)版速度,Cloud Profle還沒完全收集好就上新版,導(dǎo)致Cloud Proflie失效。還有一個(gè)背景是Jetpack Compose 不是系統(tǒng)代碼称杨,因此沒有完全編譯成機(jī)器碼,而且Jetpack Compose庫比較大笨奠,因此在Profile生成之前使用了Jetpack Compose的應(yīng)用啟動(dòng)會(huì)產(chǎn)生性能問題赂弓。最后Google為了解決這些問題乡范,創(chuàng)造了收集Profile的BaselineProfileRule Macrobenchmark以及使用Profile的ProfileInstaller。

使用Baseline Profile的機(jī)制可以在Android7及以上的手機(jī)上得到應(yīng)用的啟動(dòng)加速瓶佳,因?yàn)閺纳鲜鲋繟ndroid7就已經(jīng)開始有PGO(Profile-guided optimization)的編譯方式。生成的Profile文件會(huì)打包到apk里面贴彼,并且會(huì)結(jié)合Google Play的Cloud Profile來引導(dǎo)AOT編譯器仗。雖然在國內(nèi)基本上用不了Cloud Profile剃斧,不過Baseline Profile是可以獨(dú)立于Google Play單獨(dú)使用的。

image.png

在使用了Baseline Proflie之后,有道詞典的啟動(dòng)速度從線上統(tǒng)計(jì)上看球散,冷啟動(dòng)時(shí)間有15%的提升。

這篇文章主要介紹了Android Runtime的演進(jìn)以及對于應(yīng)用啟動(dòng)的影響泻蚊,下一篇文章我會(huì)詳細(xì)介紹關(guān)于Profile&dex文件優(yōu)化羹奉、Baseline Profile工具庫原理,以及在實(shí)際操作上如何使用的問題细卧,敬請大家期待一下翰苫!

參考

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末棚潦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子纬朝,更是在濱河造成了極大的恐慌蜓萄,老刑警劉巖辟犀,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件出嘹,死亡現(xiàn)場離奇詭異刁赦,居然都是意外死亡丸升,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人土至,你說我怎么就攤上這事。” “怎么了毅否?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵捆探,是天一觀的道長奴烙。 經(jīng)常有香客問我,道長丰滑,這世上最難降的妖魔是什么擎宝? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮涂屁,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘栈源。我一直安慰自己涣雕,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪眯搭。 梳的紋絲不亂的頭發(fā)上笔时,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼俯邓。 笑死引镊,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的琴拧。 我是一名探鬼主播除师,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼倚舀,長吁一口氣:“原來是場噩夢啊……” “哼风罩!你這毒婦竟也來了入宦?” 一聲冷哼從身側(cè)響起盈滴,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎烈菌,沒想到半個(gè)月后济瓢,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柬帕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年盼铁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片当辐。...
    茶點(diǎn)故事閱讀 38,059評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖袖裕,靈堂內(nèi)的尸體忽然破棺而出堰酿,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布帽蝶,位于F島的核電站,受9級特大地震影響趣避,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一惜论、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春棕洋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工断盛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓征椒,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子溉躲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容