熱修&插件 - 編譯

本專題梳理下熱修插件相關知識點向瓷,后續(xù)也好翻閱回顧。

開篇先簡單梳理一些相關基本概念箩绍。

一截碴、編譯相關文件介紹

libdvm.so dalvik庫文件梳侨。android 5.0之前使用,5.0及之后切換為libart.so
libart.so art庫文件日丹。zygote啟動時main方法中執(zhí)行AndroidRuntime::start走哺,加載libart.so。
dex2oat /system/bin目錄下的編譯腳本哲虾。

.dex 符合android虛擬機規(guī)范的字節(jié)碼文件丙躏,編譯的源文件。
.vdex 存儲預先驗證的dex文件束凑,在有效期內(nèi)能減少不必要的dex文件驗證彼哼。
.odex 包含了完整的dex文件和編譯后的機器碼。在有效期內(nèi)可以直接執(zhí)行編譯好的機器碼湘今。.oat文件已被.odex取代
.art Image文件,記錄應用啟動熱點函數(shù)相關地址剪菱,方便尋址摩瞎。在speed-profile模式下根據(jù)熱點函數(shù)進行類的預加載,預加載后的類可以直接map到內(nèi)存中使用孝常,不需要從dex中加載解析旗们。

文件所在目錄:
主apk包

/data/app/cn.com.sina.sports--15rQHIm3VJ-9s1v4EUDfQ== # ls

base.apk lib oat

編譯后生成的文件目錄:一般應用安裝后就會生成這三個文件

/data/app/cn.com.sina.sports--15rQHIm3VJ-9s1v4EUDfQ==/oat/arm or arm64 # ls

base.art base.odex base.vdex

歷史演變:

版本 特點
<=6.0 輸出只有odex文件,其中包含了完整的dex文件和編譯后的機器碼构灸。
7.0 輸出文件有odex和art文件上渴。
8.0 輸出文件有odex、art和vdex文件。

簡單說:.vdex就是優(yōu)化文件驗證稠氮,.art就是優(yōu)化類加載曹阔。

二、 編譯方式

歷史演變:

版本 原理 優(yōu)缺點
Android 4.x(Interpreter + JIT) 代碼默認走解釋器隔披,但熱點函數(shù)會執(zhí)行JIT進行即時編譯 優(yōu)點:占用內(nèi)存少
缺點:退出app下次啟動需要重復編譯赃份。
Android 5.0/5.1/6.0(interpreter + AOT) 在AOT模式下,App在安裝過程時奢米, 就會完成所有編譯抓韩。 優(yōu)點:性能好
缺點:App安裝時間長,占用存儲空間多鬓长。
Android 7.0之后(Interpreter + JIT + AOT) 代碼默認走解釋器谒拴,但熱點函數(shù)會執(zhí)行JIT進行即時編譯,在特定場景下會按compile-filter進行AOT編譯 比較于純AOT模式:安裝時間縮短涉波,占用存儲空間相對少些英上。比較于純JIT,性能更好怠蹂。

編譯方式:具有JIT(Just-In-Time)AOT(Ahead-of-Time)兩種編譯方式善延。
執(zhí)行方式:解釋器執(zhí)行 和 執(zhí)行編譯后的機器碼 兩種執(zhí)行方式。

機器碼生成方式:JIT生成的機器碼緩存在內(nèi)存中城侧,優(yōu)化解釋模式的執(zhí)行易遣,屬于運行時優(yōu)化。而OAT生成的機器碼緩存為文件嫌佑,屬于持久化優(yōu)化豆茫,每次編譯會更新文件,但是更新頻率并不高屋摇。

使用dex2oat進行AOT編譯的compile filter:

  • verify:只運行 DEX 代碼驗證揩魂。
  • quicken:運行 DEX 代碼驗證,并優(yōu)化一些 DEX 指令炮温,以獲得更好的解釋器性能火脉。
  • speed-profile:運行 DEX 代碼驗證,并對配置文件中列出的方法進行 AOT 編譯柒啤。
  • speed:運行 DEX 代碼驗證倦挂,并對所有方法進行 AOT 編譯。

三担巩、系統(tǒng)觸發(fā)OAT編譯的時機

路徑 描述 編譯方式 編譯內(nèi)容
Install 應用安裝觸發(fā)的編譯 speed-profile 主apk
OTA升級 系統(tǒng)升級觸發(fā)的編譯 verify 主apk
load dexFile 動態(tài)加載插件觸發(fā)的編譯 quicken 插件
postboot 開機1分鐘后方援,jobService觸發(fā)的編譯 verify 主apk
idle&charge 同時滿足charge、idle狀態(tài)且24小時內(nèi)只觸發(fā)一次涛癌,主apk通過installd觸發(fā)編譯,插件通過虛擬機觸發(fā)編譯 speed-profile 主apk 和 插件

注:OTA編譯是通過dex2oat腳本執(zhí)行的犯戏。

四送火、源碼中觸發(fā)dex2oat編譯的兩條路徑

4.1 由Installd觸發(fā)

核心方法:

frameworks/base/services/core/java/com/android/server/pm/PackageDexOptimizer.java

private int dexOptPath(PackageParser.Package pkg, String path, String isa,
String compilerFilter, boolean profileUpdated, String classLoaderContext,
int dexoptFlags, int uid, CompilerStats.PackageStats packageStats, boolean downgrade,
String profileName, String dexMetadataPath, int compilationReason) {
   //判斷是否主要做dex2oat編譯
   int dexoptNeeded = getDexoptNeeded(path, isa, compilerFilter, classLoaderContext,
profileUpdated, downgrade);
if (Math.abs(dexoptNeeded) == DexFile.NO_DEXOPT_NEEDED) {
       return DEX_OPT_SKIPPED;
}
...
//通過installd走dex2oat編譯
mInstaller.dexopt(path, uid, pkg.packageName, isa, dexoptNeeded, oatDir, dexoptFlags,
compilerFilter, pkg.volumeUuid, classLoaderContext, pkg.applicationInfo.seInfo,
false /* downgrade*/, pkg.applicationInfo.targetSdkVersion,
profileName, dexMetadataPath,
getAugmentedReasonName(compilationReason, dexMetadataPath != null));
...
}

這個方法主要就干了兩件事:判斷是否需要做dex2oat 和 通過Installer binder call給installd(7.0及之前它與Installer進行socket通信) 去執(zhí)行dexopt操作。

4.2 加載dex流程觸發(fā)

編譯的核心方法在oat_file_manager.cc中的OpenDexFilesFromOat,這里通過oat_file_assistant.cc執(zhí)行isUpToDate判斷dex文件是否需要編譯先匪,如果需要走它的MakeUpToDate方法种吸,執(zhí)行編譯。MakeUpToDate中如果需要執(zhí)行編譯會走GenerateOatFileNoChecks胚鸯,最終調(diào)用其Dex2Oat方法骨稿,調(diào)整好參數(shù)傳給dex2oat這個執(zhí)行文件去Exec。

參考:
https://source.android.com/devices/tech/dalvik/jit-compiler
https://source.android.com/devices/tech/dalvik/configure
https://www.zhihu.com/question/55652975
https://www.zhihu.com/question/275955357

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載姜钳,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者坦冠。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市哥桥,隨后出現(xiàn)的幾起案子辙浑,更是在濱河造成了極大的恐慌,老刑警劉巖拟糕,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件判呕,死亡現(xiàn)場離奇詭異,居然都是意外死亡送滞,警方通過查閱死者的電腦和手機侠草,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來犁嗅,“玉大人边涕,你說我怎么就攤上這事」游ⅲ” “怎么了功蜓?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長宠蚂。 經(jīng)常有香客問我式撼,道長,這世上最難降的妖魔是什么求厕? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任著隆,我火速辦了婚禮,結果婚禮上呀癣,老公的妹妹穿的比我還像新娘旅东。我一直安慰自己,他們只是感情好十艾,可當我...
    茶點故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腾节,像睡著了一般忘嫉。 火紅的嫁衣襯著肌膚如雪荤牍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天庆冕,我揣著相機與錄音康吵,去河邊找鬼。 笑死访递,一個胖子當著我的面吹牛晦嵌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播拷姿,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼惭载,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了响巢?” 一聲冷哼從身側響起描滔,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎踪古,沒想到半個月后含长,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡伏穆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年拘泞,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片枕扫。...
    茶點故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡陪腌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出铡原,到底是詐尸還是另有隱情偷厦,我是刑警寧澤,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布燕刻,位于F島的核電站只泼,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏卵洗。R本人自食惡果不足惜请唱,卻給世界環(huán)境...
    茶點故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望过蹂。 院中可真熱鬧十绑,春花似錦、人聲如沸酷勺。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽脆诉。三九已至甚亭,卻和暖如春贷币,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背亏狰。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工役纹, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人暇唾。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓促脉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親策州。 傳聞我的和親對象是個殘疾皇子瘸味,可洞房花燭夜當晚...
    茶點故事閱讀 44,577評論 2 353

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