歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux基礎 >> Linux教程 >> Dalvik虛擬機和JVM的對比

Dalvik虛擬機和JVM的對比

日期:2017/2/28 13:58:31   编辑:Linux教程

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代碼和C\C++代碼中互相調用函數。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核心庫而節省了內存空間。

Copyright © Linux教程網 All Rights Reserved