
這是一篇給自己腦補(bǔ)的筆記!
想必很多Android用戶已經(jīng)在自己各種設(shè)備上使用Android L了。自己年初在淘寶上¥1200進(jìn)了nexus5,系統(tǒng)早早的升級(jí)到Android L,不得不說(shuō)Nexus是一個(gè)非常非常棒的手機(jī)。
Android L與之前Android KK的對(duì)比,Dalvik虛擬機(jī)已經(jīng)在L中移除,ART(Android run time)在kk的時(shí)候作為Optional,現(xiàn)在已經(jīng)正式代替Dalvik。講到這些轉(zhuǎn)變的時(shí)候,疑問(wèn)就來(lái)了而且還根本停不下來(lái),我不知道Dalvik之前是怎么做的,Java于我只是大學(xué)一個(gè)學(xué)期的課程,Java虛擬機(jī),我當(dāng)時(shí)在課堂上絞盡腦汁也想不出一個(gè)具體樣子出來(lái),然后渾渾噩噩,大學(xué)就過(guò)去了,好吧我想知道java在傳統(tǒng)JVM中是如何運(yùn)行的,在DVM中又是如何運(yùn)行的,什么是dex,什么是odex,什么是JIT,什么是AOT,什么是oat,什么是ART...?有時(shí)想想,想這么多真的好嘛???不過(guò)沒(méi)辦法,有時(shí)腦子蹦蹦出來(lái)這么多疑問(wèn),實(shí)在憋不下去就會(huì)覺(jué)得有必要抽個(gè)時(shí)間腦補(bǔ)一下。
dex
本質(zhì)上java文件編譯后都是字節(jié)碼ByteCode,不管是傳統(tǒng)的JVM,還是Google Dalvik DVM。只是這兩種虛擬機(jī)環(huán)境下ByteCode有所差異,最直觀的是在JVM運(yùn)行的是.class文件,而DVM是.dex文件,DVM專門對(duì)移動(dòng)操作系統(tǒng)(尤其是Android)的特性進(jìn)行了優(yōu)化,并且DVM的設(shè)計(jì)是基于寄存器的,指令集有非常大的不同(具體未研究),還有等等等等...,好吧,到這步,了解到.dex是字節(jié)碼,至于dex文件format構(gòu)成,腦補(bǔ)階段暫時(shí)略過(guò)吧XD~~。
JIT
接下來(lái)Android2.2的時(shí)候引入了JIT(JUST-IN-TIME)技術(shù),JIT技術(shù)準(zhǔn)確來(lái)講應(yīng)該是JIT Compiler,那JIT之前是怎么一回事?最早的時(shí)候,java是由解釋器(Interpreter),將每個(gè)java指令轉(zhuǎn)譯為對(duì)等的微處理器指令,并根據(jù)轉(zhuǎn)譯后的指令先后次序依序執(zhí)行,一個(gè)java指令可能對(duì)應(yīng)十幾或者幾十個(gè)對(duì)等微處理指令,運(yùn)行的時(shí)候還要先解釋,在硬件條件差的情況下,執(zhí)行速度是可想而知有多慢的。為了解決這個(gè)問(wèn)題,JIT就來(lái)了,當(dāng)java執(zhí)行runtime環(huán)境時(shí),每遇到一個(gè)class,JIT就會(huì)對(duì)這個(gè)類進(jìn)行編譯,生成相當(dāng)精簡(jiǎn)的二進(jìn)制碼,花費(fèi)少許的編譯時(shí)間來(lái)?yè)Q取后續(xù)的執(zhí)行速率,這個(gè)效率提高還是比較大的,但這并沒(méi)有達(dá)到頂尖的效能,因?yàn)槟承﹋ava文件是極少執(zhí)行的,編譯它們的時(shí)間有可能遠(yuǎn)遠(yuǎn)長(zhǎng)于轉(zhuǎn)譯器轉(zhuǎn)譯執(zhí)行的時(shí)間,整體下來(lái),花費(fèi)的時(shí)間并沒(méi)有減少。基于JIT的經(jīng)驗(yàn),又出來(lái)了動(dòng)態(tài)編譯器(dynamic compiler),動(dòng)態(tài)預(yù)判哪些需要compile哪些需要轉(zhuǎn)譯,所以動(dòng)態(tài)編譯器是既包含了轉(zhuǎn)譯器&編譯器的。尚不確定Android的JIT技術(shù)是否為這種dynamic compiler。另外,說(shuō)到這里,我們第一次執(zhí)行APP速度慢一些應(yīng)該是因?yàn)樵谧鲆恍〤ompile的動(dòng)作,如果說(shuō)得不對(duì),還請(qǐng)指正。google當(dāng)時(shí)說(shuō),JIT技術(shù)的引入速度提升3-5倍,后來(lái)發(fā)現(xiàn)我們?nèi)A麗麗的又被騙了。
Odex
講了dex、JIT,接下來(lái)講講Odex,Odex即Optimize Dex對(duì)dex文件的優(yōu)化,最直觀的好處:
- deodex在系統(tǒng)第一次開(kāi)機(jī)時(shí),需要提取所有apk里的dex文件,而odex優(yōu)化是提前提取出來(lái)了,開(kāi)機(jī)速度&運(yùn)行速度都有提高。
- Odex優(yōu)化后,APK里可以沒(méi)有dex文件,而未Odex在APK包里有一份dex文件,在/data/dalvik-cache下還有提取出來(lái)的一份,浪費(fèi)存儲(chǔ)空間。
- 一定程度上保護(hù)了廠商自己的APK,因?yàn)閍pk里只有資源文件,反匯編沒(méi)有意義,直接拷貝到別處無(wú)法安裝運(yùn)行...。
AOT
技術(shù)隨著時(shí)間之輪毫不停歇前行。Android kitkat 4.4,新的Android Runtime(ART)出現(xiàn)了,做為一個(gè)可選項(xiàng),供一些愿意的用戶測(cè)試使用,當(dāng)然這個(gè)時(shí)候Dalvik還是作為默認(rèn)的虛擬機(jī)環(huán)境。ART采取了AOT(Ahead-Of-Time)技術(shù),簡(jiǎn)單一點(diǎn)理解就是,在APK安裝的時(shí)候就會(huì)做預(yù)先編譯動(dòng)作,編譯好的文件是OAT文件,該文件本質(zhì)上是一個(gè)ELF文件,這里與dex(Odex)文件最大的區(qū)別是OAT文件不再是字節(jié)碼文件,而是一個(gè)可執(zhí)行文件,可以更底層的與硬件接觸,運(yùn)行時(shí)也省去了預(yù)編譯和轉(zhuǎn)譯的時(shí)間。在Android L中我們找不到OAT文件,其實(shí)oat文件依舊以.odex作為后綴,通過(guò)file命令或者UE打開(kāi)可以看到ELF頭部。另外ART設(shè)計(jì)是考慮兼容性的,即在Dalvik可以運(yùn)行的APP,在系統(tǒng)升級(jí)到5.0、5.1(Dalvik->ART)這些APP依舊可以運(yùn)行,這個(gè)是通過(guò)dex2oat做到的,dalvik下的dex、odex文件均可以通過(guò)這個(gè)工具轉(zhuǎn)化為oat文件,并且odex文件將比dex文件編譯的更快。
腦補(bǔ)暫告一段落,歡迎客官拍磚、指正。
References:
http://www.importnew.com/596.html
http://bbs.mfunz.com/thread-1007717-1-1.html
http://source.android.com/devices/tech/dalvik/configure.html
http://source.android.com/devices/tech/dalvik/index.html
http://www.th7.cn/Program/Android/201401/168089.shtml