Dalvik虛擬機
DVM是Dalvik Virtual Machine的縮寫,是Android4.4及以前使用的虛擬機,所有android程序都運行在android系統(tǒng)進程里,每個進程對應著一個Dalvik虛擬機實例。
DVM和JVM的區(qū)別
-
執(zhí)行的字節(jié)碼不同
- JAVA虛擬機運行的是JAVA字節(jié)碼,Dalvik虛擬機運行的是Dalvik字節(jié)碼
JVM: .java -> javac -> .class -> jar -> .jar DVM: .java -> javac -> .class -> dx.bat -> .dex- Dalvik可執(zhí)行文件體積更小
一般情況下,Java類文件中包含多個不同的方法簽名,如果其他的類文件引用該類文件中的方法,方法簽名也會被復制到其類文件中,也就是說,多個不同的類會同時包含相同的方法簽名,同樣地,大量的字符串常量在多個類文件中也被重復使用。這些冗余信息會直接增加文件的體積,同時也會嚴重影響虛擬機解析文件的效率。
安卓使用Dalvik虛擬機,SDK中有個dx工具負責將JAVA字節(jié)碼轉換為Dalvik字節(jié)碼,dx工具對JAVA類文件重新排列,將所有JAVA類文件中的常量池分解,消除其中的冗余信息,重新組合形成一個常量池,所有的類文件共享同一個常量池,使得相同的字符串、常量在DEX文件中只出現(xiàn)一次,從而減小了文件的體積。
-
基于的架構不同
Dvm基于寄存器,所以它的指令是二地址和三地址混合,指令中指明了操作數的地址;jvm基于棧,它的指令是零地址,指令的操作數對象默認是操作數棧中的幾個位置。但基于寄存器的指令由于需要指定源地址和目標地址,因此需要占用更多的指令空間。Java虛擬機基于棧架構。程序在運行時虛擬機需要頻繁的從棧上讀取或寫入數據,這個過程需要更多的指令分派與內存訪問次數, 會耗費不少CPU時間, 對千像手機設備資源有限的設備來說, 這是相當大的一筆開銷。Dalvik 虛擬機基于寄存器架構。數據的訪問通過寄存器間直接傳遞, 這樣的訪問方式比基千棧方式要快很多。
Dalvik堆
Dalvik虛擬機用來分配對象的堆劃分為兩部分,一部分叫做Active Heap,另一部分叫做Zygote Heap。Android系統(tǒng)啟動后,會有一個Zygote進程創(chuàng)建第一個Dalvik虛擬機,它只維護了一個堆。以后啟動的所有應用程序進程是被Zygote進程fork出來的,并都持有一個自己的Dalvik虛擬機。在創(chuàng)建應用程序的過程中,Dalvik虛擬機采用COW策略復制Zygote進程的地址空間。
當創(chuàng)建第一個應用程序進程時,會將已經使用了的那部分堆內存劃分為一部分,還沒有使用的堆內存劃分為另外一部分。前者就稱為Zygote堆,后者就稱為Active堆。這樣只需把zygote堆中的內容復制給應用程序進程就可以了。以后無論是Zygote進程,還是應用程序進程,當它們需要分配對象的時候,都在Active堆上進行。這樣就可以使得Zygote堆盡可能少地被執(zhí)行寫操作,因而就可以減少執(zhí)行寫時拷貝的操作。在Zygote堆里面分配的對象其實主要就是Zygote進程在啟動過程中預加載的類、資源和對象了。這意味著這些預加載的類、資源和對象可以在Zygote進程和應用程序進程中做到長期共享。這樣既能減少拷貝操作,還能減少對內存的需求。Dalvik虛擬機進行部分垃圾收集時,實際上就是只收集在Active堆上分配的對象。
Art虛擬機
為了區(qū)分Art虛擬機和Dalvik虛擬機,需要先介紹下面兩個概念。
JIT
JIT(Just-in-time Compilation,即時編譯),又稱為動態(tài)編譯,是一種通過在運行時將字節(jié)碼翻譯為機器碼的技術,使得程序的執(zhí)行速度更快。
在JVM中,javac將源程序編譯成java字節(jié)碼,JVM通過逐條解釋將字節(jié)碼翻譯成對應的機器指令,逐條讀入,逐條解釋翻譯,比較慢;為了提升速度,當App運行時,每當遇到一個新類,JIT編譯器就會對這個類進行編譯,經過編譯后的代碼,會被優(yōu)化成相當精簡的原生型指令碼(即native code),這樣在下次執(zhí)行到相同邏輯的時候,速度就會更快。
但是,有一點需要注意,dex字節(jié)碼翻譯成本地機器碼是發(fā)生在應用程序的運行過程中的,并且應用程序每一次重新運行的時候,都要做重做這個翻譯工作,每次重新打開App,都需要JIT編譯。AOT
ART的策略與Dalvik不同,在ART 環(huán)境中,應用在第一次安裝的時候,字節(jié)碼就會預先編譯成機器碼,使其成為真正的本地應用。APK在安裝的時候,打包在里面的classes.dex文件會被工具dex2oat翻譯成本地機器指令,最終得到一個ELF格式的oat文件。
這樣可以保證以后每次打開應用,執(zhí)行的都是本地機器碼。去除了運行時的解釋執(zhí)行,效率更高,啟動更快。-
ART和Dalvik的區(qū)別
- ART需要應用程序在安裝時,就把程序代碼轉換成機器語言,所以這會消耗掉更多的存儲空間,但消耗掉空間的增幅通常不會超過應用代碼包大小的20%
- 由于有了一個轉碼的過程,所以應用安裝時間難免會延長
參考文章: