中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

9102年了,還不知道Android為什么卡?

2021-01-29    分類: 網(wǎng)站建設(shè)

導(dǎo)讀

最近華為方舟編譯器要開源了,筆者去看了下發(fā)布會(huì)PPT,發(fā)現(xiàn)作為一名Android開發(fā)者,PPT中所介紹的知識(shí)點(diǎn)我居然不能完全看懂?于是乎惡補(bǔ)了下PPT中的內(nèi)容,整理成本文。

在開發(fā)階段Java源代碼在開發(fā)階段打包成.dex文件,C語(yǔ)言直接就是.so庫(kù),因?yàn)镃語(yǔ)言本身就是編譯語(yǔ)言。

在用戶手機(jī)中,APK中的.dex文件(字節(jié)碼)會(huì)被解釋為.oat文件(機(jī)器碼)運(yùn)行在ART虛擬機(jī)中,.so庫(kù)則為計(jì)算機(jī)可以直接運(yùn)行的二進(jìn)制代碼(機(jī)器碼),兩份機(jī)器碼要互相調(diào)用肯定是有開銷的。

下面就來(lái)闡述下為什么兩份機(jī)器碼會(huì)不同。

這邊需要深入理解字節(jié)碼->機(jī)器碼的編譯過程,在圖上雖然都被編譯成了機(jī)器碼,都能被硬件直接調(diào)用,但是兩份機(jī)器碼的性能,效率,實(shí)現(xiàn)方式相差甚多,這主要是由以下兩個(gè)點(diǎn)造成的:

  • 編程語(yǔ)言不同導(dǎo)致編譯出的字節(jié)碼不同導(dǎo)致編譯出的機(jī)器碼不同。
  • 舉個(gè)例子,針對(duì)同樣是靜態(tài)語(yǔ)言的C和Java,對(duì)int a + b 的運(yùn)算
  • C語(yǔ)言可以直接加載內(nèi)存,在寄存器中計(jì)算,這是由于C語(yǔ)言是靜態(tài)語(yǔ)言,a和b是確定的int對(duì)象。

在Java中雖然定義對(duì)象我們也要明確的指出對(duì)象的類型,例如int a = 0,但是Java擁有動(dòng)態(tài)性,Java擁有反射,代理,誰(shuí)也不敢保證a在被調(diào)用時(shí)還是int類型,所以Java的編譯需要考慮上下文關(guān)系,即具體情況具體編譯。

所以連字節(jié)碼已經(jīng)不同了,編譯出的機(jī)器碼肯定不同。

運(yùn)行環(huán)境不同導(dǎo)致編譯出的機(jī)器碼不同

圖中明顯看到由Java編譯而來(lái)的機(jī)器碼包裹在ART中,ART全稱Android RunTime,即安卓運(yùn)行環(huán)境,跟虛擬機(jī)差不多是一個(gè)意思。而C語(yǔ)言所在的運(yùn)行環(huán)境不在ART中。

RunTime提供了基本的輸入輸出或是內(nèi)存管理等支持,如果要在兩個(gè)不同的RunTime中互相調(diào)用,則必然有額外開銷。

舉個(gè)例子,由于Java有GC(垃圾回收機(jī)制),在Java中的一個(gè)對(duì)象地址不是固定的,有可能被GC挪動(dòng)了。即在ART環(huán)境中跑的機(jī)器碼中的對(duì)象的地址不固定。可是C語(yǔ)言哪管那么多幺蛾子,C就直接問Java要一個(gè)對(duì)象的地址,但萬(wàn)一這個(gè)對(duì)象地址被挪動(dòng)了,那就完蛋了。解決方案有兩個(gè):

把這個(gè)對(duì)象在C里再拷一份。很明顯這造成了很大的開銷。

告訴ART,我要用這個(gè)對(duì)象了,GC這個(gè)對(duì)象的地址你不能動(dòng)!你先一邊呆著去。這樣相對(duì)而言開銷倒是小了,但如果這個(gè)地址如果一直不能被回收的話,可能造成OOM。

(此處參考知乎@張鐸在華為公布的方舟編譯器到底對(duì)安卓軟件生態(tài)會(huì)有多大影響?中的回答)

3. 字節(jié)碼的編譯模板——未針對(duì)具體APP進(jìn)行優(yōu)化

我們舉個(gè)例子來(lái)理解編譯模版,“Hello world”可以被翻譯為“你好,世界”,同樣也可以被翻譯為“世界,你好”,這個(gè)差別就是編譯模版不同導(dǎo)致的,

①. 統(tǒng)一的編譯模版(vm模版)

字節(jié)碼可以通過不同的編譯模版被編譯為機(jī)器碼,而編譯模版的不同將直接導(dǎo)致編譯完后的機(jī)器碼性能大相徑庭。

上圖的流程說明了在特殊情況下,AOT編譯實(shí)則不起作用,完全是靠解釋器和JIT在進(jìn)行實(shí)時(shí)編譯,整個(gè)編譯方案退步到了Android2.2時(shí)期。

③. 聰明的ART

雖然這個(gè)問題存在,但并不是特別嚴(yán)重。因?yàn)锳RT并沒有我說的那么笨。在之后應(yīng)用使用過程中,ART會(huì)記錄并學(xué)習(xí)用戶的使用習(xí)慣(保存熱點(diǎn)代碼),然后更新針對(duì)當(dāng)前APP的定制化vm模版,不斷的補(bǔ)充熱點(diǎn)代碼,補(bǔ)充定制化模版。

這是不是聽起來(lái)很熟悉?在手機(jī)發(fā)布大會(huì)上的宣傳語(yǔ)“基于用戶操作習(xí)慣進(jìn)行學(xué)習(xí),APP打開速度不斷提高”的部分原理就是這個(gè)。

④. 最終大招,一勞永逸

其實(shí)要一勞永逸的解決這個(gè)問題思路也不難:我們只需要在吃飯前跟老板提前預(yù)定想吃啥就行,讓老板先準(zhǔn)備起來(lái),這樣等我們到了就不用等餐了。

在最新的Android9.0版本中,谷歌推出了這個(gè)類似提前預(yù)定的功能:編譯系統(tǒng)支持在具有藍(lán)圖編譯規(guī)則的原生 Android 模塊上使用 Clang 的配置文件引導(dǎo)優(yōu)化 (PGO)。

說人話:谷歌允許你在開發(fā)階段添加一個(gè)配置文件,這個(gè)配置文件內(nèi)可指定“熱點(diǎn)代碼”,當(dāng)應(yīng)用安裝完后,ART在后臺(tái)悄悄編譯APP時(shí),會(huì)優(yōu)先編譯配置文件中指定的“熱點(diǎn)代碼”。

雖然谷歌支持,但是這塊技術(shù)對(duì)于APP開發(fā)人員而言國(guó)內(nèi)資料過于缺乏,普及面不廣。筆者先貼上官方鏈接,以及這篇博客,其中介紹的還是挺詳細(xì)的。(隔壁Xcode針對(duì)PGO都有UI界面了)

三、解決思路

解決思路總結(jié)為四個(gè)字就是:華為方舟。

方舟的解決思路:

  1. 針對(duì)虛擬機(jī)問題,方舟說:我不要你這個(gè)爛虛擬機(jī)了,我們裸奔
  2. 針對(duì)JNI調(diào)用問題,方舟說:我們讓Java在編譯階段跟C一樣直接編譯成機(jī)器碼,干掉虛擬機(jī),跟.so庫(kù)直接調(diào)用,毫無(wú)JNI開銷問題
  3. 針對(duì)編譯模版問題,方舟說:我們支持針對(duì)不同APP進(jìn)行不同的編譯優(yōu)化

總結(jié)一下:方舟支持在打包編譯階段針對(duì)不同APP進(jìn)行不同的編譯優(yōu)化,然后直接打包成機(jī)器碼.apk(很可能已經(jīng)不叫apk了),然后直接運(yùn)行。

這樣看起來(lái)方舟確實(shí)解決掉了三大問題,但是,代價(jià)呢?

如果按照這個(gè)思路,方舟就肯定不止是一個(gè)編譯器了,它應(yīng)該還有一套自己的runtime。當(dāng)然這些都是后話了。

關(guān)于方舟的實(shí)現(xiàn)只是大概講了思路,但沒有深入,因?yàn)橐粊?lái)方舟沒開源,二來(lái)方舟發(fā)布會(huì)PPT營(yíng)銷層面更多,技術(shù)細(xì)節(jié)缺少,現(xiàn)在奇思妙想完全是紙上談兵,一切還是靜待開源吧。

本文標(biāo)題:9102年了,還不知道Android為什么卡?
分享URL:http://www.rwnh.cn/news46/98096.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供標(biāo)簽優(yōu)化、建站公司軟件開發(fā)、服務(wù)器托管營(yíng)銷型網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名
陈巴尔虎旗| 郴州市| 招远市| 城固县| 保靖县| 呼伦贝尔市| 鹤庆县| 嘉荫县| 竹山县| 东阳市| 揭东县| 论坛| 永定县| 绍兴市| 民和| 湘潭市| 邯郸县| 定安县| 托克逊县| 博野县| 西丰县| 济阳县| 龙游县| 石嘴山市| 门头沟区| 霞浦县| 海盐县| 绩溪县| 洱源县| 保德县| 黄浦区| 略阳县| 格尔木市| 通化县| 东乡族自治县| 庄浪县| 朝阳县| 揭东县| 莲花县| 堆龙德庆县| 横山县|