2021-05-12 14:32:11
Dalvik虛擬機器和JVM的對比
Dalvik虛擬機器與Java虛擬機器有著很多相似的特性,都支援GC,JIT,JNI等等。其主要區別在於檔案格式以及指令集不同,下面對兩者的特性進行比較與討論。
Difference1:檔案格式
Dalvik的虛擬機器類檔案採用dex格式,而JVM的類檔案是class格式。不同之處在於,我們熟悉的class位元組碼檔案中只包含一個類,而dex檔案中可以包含多個類。其好處在於多個類中重複的常數和字串只會儲存一份,一定程度上節省了空間,更適於在手機上執行。
Difference2:指令集
Dalvik的指令集基於暫存器,而JVM的指令集基於堆疊。不同之處在於,基於暫存器的指令在暫存器中定址,速度更快但指令長度長;基於堆疊的指令集更短,但占用CPU時間較多。其對比類似於CISC與RISC的對比。從移植性而言,顯然基於堆疊的指令集可移植性更好,它不針對目標機器的暫存器做任何優化。而基於寄存機的指令集可以再程式執行之前針對目標機器的暫存器對程式進行優化,這種優化是在編譯過程中的優化,並非類似於JIT在執行過程中的動態優化,但最終目標都是將程式轉化成本地機器語言。
下面,針對Dalvik虛擬機器的記憶體管理,JIT,垃圾收集、JIT、JNI以及進程和執行緒管理進行討論。
記憶體管理
Dalvik虛擬機器的記憶體大體上可以分為三個部分:Java Object Heap、Bitmap Memory和Native Heap。
Java Object Heap用來存放Java物件,不同手機廠商對其大小有不同的設定,可以通過ActivityManager的getMemoryClass獲取其最大值,該值是Android應用所能使用的最大記憶體。
Bitmap Memory用於存放和處理圖片。在Android3.0之前,Bitmap Memory是Native Heap的一部分,其大小計入Java Object Heap,即bitmap和其他java物件所佔用的記憶體不能超過上面JOH的最大值。在Android3.0之後,Bitmap Memory直接在JOH中分配,便於GC。
Native Heap是本地機器語言申請分配的記憶體。
垃圾回收
在Android2.3之前的版本中,Dalvik虛擬機器的垃圾回收策略如下:
垃圾收集執行緒在執行的時候,其它的執行緒都停止,從而一次收集完全部的垃圾,這樣導致的結果就是一次垃圾收集造成的程式中止時間通常都大於100ms。
在Android2.3之後,垃圾收集執行緒與其它執行緒是並行執行,一次可能只收集一部分垃圾,使得一次垃圾收集造成的程式中止時間大大降低,通常都小於5ms。
JIT
JIT是在程式執行的過程中進行編譯,將反復呼叫的程式碼轉化為本地機器碼儲存起來,這個過程是在執行時動態執行的,相對於程式編譯時的優化而言,JIT會佔用程式執行時間。Android2.2之後才開始支援JNI。
本地呼叫
Java程式執行在虛擬機器上,需要將程式翻譯成目標機器的指令來執行,有些功能需要呼叫目標機器作業系統介面來完成。Java的本地呼叫可以幫助我們在Java程式碼和CC++程式碼中互相呼叫函數。Android提供了NDK來幫助我們實現JNI。
執行緒管理
Android的進程主要有兩個特點:
每一個Android APP進程都有一個Dalvik虛擬機器範例,這保證了多個app在執行時互不影響。
每一個Android應用程式進程都是由一種Zygote的進程fork出來的。而Zygote進程是由初始化進程創造出來的。Zygote進程在啟動的時候,會建立一個虛擬機器範例,並且在這個虛擬機器範例將所有的Java核心庫都載入起來。每當Zygote進程需要建立一個Android應用程式進程的時候,它就通過複製自身來實現,也就是通過fork系統呼叫來實現。這些被fork出來的Android應用程式進程,一方面是複製了Zygote進程中的虛擬機器範例,另一方面是與Zygote進程共用了同一套Java核心庫。這樣不僅Android應用程式進程的建立過程很快,而且由於所有的Android應用程式進程都共用同一套Java核心庫而節省了記憶體空間。
本文永久更新連結地址:http://www.linuxidc.com/Linux/2015-08/122328.htm
相關文章