Android Dalvik虛擬機初識

摘自:http://blog.csdn.net/andyxm/article/details/6126907安全

 

首先,讓咱們來思考下面幾個問題:架構

什麼是Dalvik虛擬機?性能

Dalvik VM與JVM有什麼區別?優化

Dalvik VM有什麼新的特色?this

Dalvik VM的架構是怎麼樣的?spa

 

首先,我得認可第一個問題問得很傻:什麼是Dalvik虛擬機?沒有人給出過一個明確的定義,可是,咱們彷佛能夠從人們對Java虛擬機的描述中獲得些信息。操作系統

 

Java虛擬機(JVM)是一個虛構出來的計算機,是經過在實際的計算機上仿真模擬各類計算機功能來實現的。它有本身完善的硬件架構(如處理器、堆棧、寄存器等),還具備相應的指令系統。使用「Java虛擬機」程序就是爲了支持與操做系統無關、在任何系統中均可以運行的程序。.net

 

所以,咱們不妨對Dalvik虛擬機做出這樣的描述: 線程

Dalvik虛擬機是Android程序的虛擬機,是Android中Java程序的運行基礎。其指令集基於寄存器架構,執行其特有的文件格式——dex字節碼來完成對象生命週期管理、堆棧管理、線程管理、安全異常管理、垃圾回收等重要功能。它的核心內容是實現庫(libdvm.so),大致由C語言實現。依賴於Linux內核的一部分功能——線程機制、內存管理機制,能高效使用內存,並在低速CPU上表現出的高性能。每個Android應用在底層都會對應一個獨立的Dalvik虛擬機實例,其代碼在虛擬機的解釋下得以執行。設計

 

與Dalvik虛擬機關係最密切的非JVM莫屬,在Android源碼readme文檔中有這樣一段話:Much of the code under this directory originally came from the Apache Harmony project, and as such contains the standard Apache header comment. Some of the code was written originally for the Android project…

 

Dalvik VM與Apache Harmony 項目關係源遠流長,所以,與JVM關係天然就密切了。

 

然而:Dalvik VM ≠Java VM

 

dalvik基於寄存器,而JVM基於stack

Dalvik執行的是特有的DEX文件格式,而JVM運行的是*.class文件格式。

 

優點:

一、在編譯時提早優化代碼而不是等到運行時

二、 虛擬機很小,使用的空間也小;被設計來知足可高效運行多種虛擬機實例。

三、常量池已被修改成只使用32位的索引,以 簡化解釋器

 

JVM的字節碼主要是零地址形式的,概念上說JVM是基於棧的架構。Google Android平臺上的應用程序的主要開發語言是Java,經過其中的Dalvik VM來運行Java程序。爲了能正確實現語義,Dalvik VM的許多設計都考慮到與JVM的兼容性;但它卻採用了基於寄存器的架構,其字節碼主要是二地址/三地址的混合形式。

 

基於棧與基於寄存器的架構,誰更快?如今實際的處理器,大多都是基於寄存器的架構,從側面反映出基於寄存器比基於棧的架構更與實際的處理器接近。但對於VM來講,源架構的求值棧或者寄存器均可能是用實際機器的內存來模擬的,因此性能特性與實際硬件又有不一樣。通常認爲基於寄存器架構的Dalvik VM比基於棧架構JVM執行效率更高,緣由是:雖然零地址指令更緊湊,但完成操做須要更多的load/store指令,也意味着更多的指令分派(instruction dispatch)次數與內存訪問次數;訪問內存是執行速度的一個重要瓶頸,二地址或三地址指令雖然每條指令佔的空間較多,但整體來講能夠用更少的指令完成操做,指令分派與內存訪問次數都較少。

 

咱們從下面的截圖能夠明瞭的看到與同一段Java代碼對應的Java bytecode 與Dalvid bytecode的比較。

專有的DEX文件格式

一個應用中會定義不少類,

編譯完成後即會有不少相應

的CLASS文件,CLASS文件

間會有很多冗餘的信息。

dex字節碼和標準Java的字節碼(Class)在結構上的一個區別是dex字節碼將多個文件整合成一個,這樣,除了減小總體的文件尺寸,I/O操做,也提升了類的查找速度。

原來每一個類文件中的常量池如今由DEX文件中一個常量池來管理。

 

DEX文件能夠進行進一步優化。優化主要是針對如下幾個方面:

一、調整全部字段的字節序(LITTLE_ENDIAN)和對齊結構中的沒一個域

二、驗證DEX文件中的全部類

三、對一些特定的類進行優化,對方法裏的操做碼進行優化

 

優化 優化後的文件大小會有所增長,應該是原DEX文件的1-4倍。

       odex是爲了在運行過程當中進一步提升性能,對dex文件的進一步優化

一個應用,一個虛擬機實例,一個進程!!!

每個Android應用都運行在一個Dalvik虛擬機實例裏,而每個虛擬機實例都是一個獨立的進程空間。每一個進程之間能夠通訊(IPC,Binder機制實現)。虛擬機的線程機制,內存分配和管理,Mutex等等都是依賴底層操做系統而實現的。

不一樣的應用在不一樣的進程空間裏運行,當一個虛擬機關閉或意外停止時不會對其它 虛擬機形成影響,能夠最大程度的保護應用的安全和獨立運行。

 

Zygote是虛擬機實例的孵化器。AndroidRuntime.cpp中ZygoteInit.main()的執行會完成一個分裂,分裂出來的子進程繼續初始化Java層的架構,這個分裂出來的進程就是system_server。每當系統要求執行一個Android應用程序,Zygote就會FORK出一個子進程來執行該應用程序。這樣作的好處顯而易見:Zygote進程是在系統啓動時產生的,它會完成虛擬機的初始化,庫的加載,預置類庫的加載和初始化等等操做,而在系統須要一個新的虛擬機實例時,Zygote經過複製自身,最快速的提供個系統。另外,對於一些只讀的系統庫,全部虛擬機實例都和Zygote共享一塊內存區域,大大節省了內存開銷。

相關文章
相關標籤/搜索