Dalvik虛擬機
dex文件
Java虛擬機運行的是java字節碼,即class文件,而Dalvik虛擬機執行的是專有的dex格式字節碼,dex文件是由一個或多個class文件打包而成。dex體積更小,class文件都有一個常量池,而dex文件只有一個常量池,多個class文件如果有重復的字符串,在dex文件里只有一份。
dex文件生成:
- javac 把.java文件編譯成.class文件
- dx工具:在sdk/build-tools/中的dx工具,執行命令dx --dex --output="文件名.dex" [class文件地址]
- 在jdk 1.8 可能會出現錯誤,提示不支持當前版本,所以編譯時要強制用低版本的jdk編譯,如javac -source 1.7 -target 1.7 [java文件]
odex文件
- odex是Optimized dex 的簡寫,即優化后的dex文件,主要是為了提高Dalvik虛擬機的運行速度。
- odex文件時dex文件具體在某個系統上的優化。odex文件優化依賴系統上的幾個核心模塊,一般是/system/framwork/下的jar包,尤其是core.jar。odex的優化及時把本來需要在執行過程中做的類校驗、調用其他類函數時的解析等工作提前處理。
Dalvik虛擬機的啟動
在Android系統中,應用程序進程都是由Zygote進程孵化出來的,而Zygote進程是由Init進程啟動的。Zygote進程在啟動時會創建一個Dalvik虛擬機實例,每當它孵化一個新的應用程序進程時,都會將這個Dalvik虛擬機實例復制到新的應用程序進程里面去,從而使得每一個應用程序進程都有一個獨立的Dalvik虛擬機實例。Zygote是虛擬機實例的孵化器。AndroidRuntime.cpp中ZygoteInit.main()的執行會完成一個分裂,分裂出來的子進程繼續初始化Java層的架構,這個分裂出來的進程就是system_server。每當系統要求執行一個Android應用程序,Zygote就會fork出一個子進程來執行該應用程序。system_server是應用與Zygote之間交流的橋梁,通過socket進行通信。Android系統啟動加載完內核后,第一個執行的是init進程,init進程首先要做的是設備的初始化工作,然后讀取inic.rc文件并啟動系統中的重要外部程序 Zygote。Zygote進程是Android所有進程的孵化器進程,它啟動后會首先初始化Dalvik虛擬機,然后啟動system_server并進入Zygote模式,通過socket等候命令。當執行一個Android應用程序時,system_server進程通過Binder IPC方式發送命令給Zygote,Zygote收到命令后通過fork自身創建一個Dalvik虛擬機的實例來執行應用程序的入口函數,這樣一個程序就啟動完成了。
Dalvik和Jvm之間的區別
- Dalvik和Jvm最大的區別是Dalvik基于寄存器結構,而Jvm基于棧結構。一般來說基于寄存器結構的運行速度更快,但代碼長度會邊長,這也是現在很多cpu采用的結構。
- Dalvik虛擬機運行dex格式的字節碼,而Jvm虛擬機運行class格式的字節碼。 Dalvik虛擬機所占空間小,且可執行文件體積小。
- 每Dalvik負責進程隔離和線程管理,每一個Android應用在底層都會對應一個獨立的Dalvik虛擬機實例,其代碼在虛擬機的解釋下得以執行。
Dalvik和ART的區別
Android Runtime,在android 5.0以后及后續版本取代Dalvik。
JIT最早在Android 2.2系統中引進到Dalvik虛擬機中,在應用程序啟動時,JIT通過進行連續的性能分析來優化程序代碼的執行,在程序運行的過程中,Dalvik虛擬機在不斷的進行將字節碼編譯成機器碼的工作。 與Dalvik虛擬機不同的是,ART引入了AOT這種預編譯技術,在應用程序安裝的過程中,ART就已經將所有的字節碼重新編譯成了機器碼。應用程序運行過程中無需進行實時的編譯工作,只需要進行直接調用。因此,ART極大的提高了應用程序的運行效率,同時也減少了手機的電量消耗,提高了移動設備的續航能力,在垃圾回收等機制上也有了較大的提升。 為了保證向下兼容,ART使用了相同的Dalvik字節碼文件(dex),即在應用程序目錄下保留了dex文件供舊程序調用然而.odex文件則替換成了可執行與可鏈接格式(ELF)可執行文件。一旦一個程序被ART的dex2oat命令編譯,那么這個程序將會指通過ELF可執行文件來運行。因此,相對于Dalvik虛擬機模式,ART模式下Android應用程序的安裝需要消耗更多的時間,同時也會占用更大的儲存空間(指內部儲存,用于儲存編譯后的代碼),但節省了很多Dalvik虛擬機用于實時編譯的時間。
核心庫:Dalvik核心庫libdvm.so,Art核心庫libart.so
Art的核心是OAT文件。OAT文件是一種Android私有ELF文件格式,它不僅包含有從DEX文件翻譯而來的本地機器指令,還包含有原來的DEX文件內容。