Java&Android 基礎知識梳理(7) Android 虛擬機

1、Dalvik 虛擬機

DalvikGoogle公司本身設計用於Android平臺的Java虛擬機,它是Android平臺的重要組成部分,支持dex格式的Java應用程序的運行。html

Dalvik做爲面向Linux、爲嵌入式操做系統設計的虛擬機,主要負責完成 對象生命週期管理、堆棧管理、線程管理、安全和異常管理,以及垃圾回收等。Dalvik充分利用Linux進程管理的特定,對其進行了面向對象的設計,使得能夠 同時運行多個進程,而傳統的Java程序一般只能運行一個進程。java

1.1 Dalvik 虛擬機和 JVM 的對比

區別一

  • 大多數的JVM虛擬機基於 棧的結構,基於棧的指令更緊湊,使用的指令只佔用一個字節,於是成爲字節碼。
  • Dalvik虛擬機則是基於 寄存器,基於寄存器的指令因爲須要指定源地址和目標地址,所以須要佔用更多的指令空間,某些指令須要佔用兩個字節。

區別二

  • Java虛擬機運行的是Java字節碼。Java類會被編譯成一個或者多個.class文件,而後打包到jar文件中,接着Java虛擬機會從相應的.class文件和.jar文件中獲取對應的字節碼。
  • Dalvik虛擬機運行的是.dex文件。在Java類被編譯成.class文件後,還會經過dx工具將全部的.class文件轉換一個.dex文件,Dalvik虛擬機再從中讀取指令和數據。.dex文件除了減小總體的文件尺寸和I/O操做次數,也提升了類的查找速度。

區別三

  • class文件中包含多個不一樣的方法簽名,若是A類文件引用B類文件中的方法,方法簽名也會被複制到A類文件中(在虛擬機加載類的鏈接階段將會使用該簽名連接到B類的對應方法),也就是說,多個不一樣的類會同時包含相同的方法簽名,一樣地,大量的字符串常量在多個類文件中也被重複使用,這些冗餘信息會直接增長文件的體積,而JVM在把描述類的數據從.class文件加載到內存時,須要對數據進行校驗、轉換解析和初始化,最終才造成能夠被虛擬機直接使用的JAVA類型,由於大量的冗餘信息,會嚴重影響虛擬機解析文件的效率。
  • .dex文件中,因爲dx工具會對JAVA類文件從新排列,將全部JAVA類文件中的常量池分解,消除其中的冗餘信息,從新組合造成一個常量池,全部的類文件共享同一個常量池,使得相同的字符串、常量在.dex文件中只出現一次,從而減少了文件的體積。

1.2 Dalvik 虛擬機特色

  • 使用dex格式的字節碼,不兼容Java字節碼格式
  • 代碼密度小,運行效率高,節省資源
  • 常量池只使用32位的索引
  • 有內存限制
  • 默認棧大小是12KB
  • 堆默認啓動大小爲2MB,默認最大值爲16MB
  • 堆支持的最小啓動大小爲1MB,支持的最大值爲1024MB
  • 堆和棧參數能夠經過-Xms-Xmx修改

1.3 Dalvik 系統架構

1.3.1 dex 文件結構

.class 文件與 .dex 文件對比

.dex文件結構和.class文件結構差別的地方不少,但從攜帶的信息上看,.dex.class文件是一致的:android

  • header:存儲了各個數據類型的起始地址、偏移量等信息。
  • proto_ids:描述函數原型信息,包括返回值,參數信息。好比「test:()V」
  • methods_ids:函數信息,包括所屬類及對應的proto信息。

雖然.dex文件的結構很緊湊,但想要運行時的性能獲得進一步提高,還須要對dex文件進行進一步優化。優化主要針對如下幾個方面:面試

  • 調整全部字段的字節序和對齊結構中的每個域
  • 驗證.dex文件中的全部類
  • 對一些特定的類進行優化,對方法裏的操做碼進行優化

.dex文件通過優化後文件大小會膨脹,大約增長到原來的1~4倍。對於內置應用,通常在系統編譯後,便會生成優化文件odex(Optimized dex)。一個Android應用程序,須要通過如下過程才能夠在Dalvik虛擬機上運行:安全

  • Java源文件編譯成.class文件
  • 使用dx工具把.class文件轉換成.dex文件
  • 使用aapt工具把.dex文件、資源文件以及AndroidManifest.xml文件組合成APK
  • APK安裝到Android設備運行

.apk 文件的產生過程

1.3.2 Dalvik 類加載器

一個dex文件須要類加載器加載原生類和Java類,而後經過解釋器根據指令集對Dalvik字節碼進行解釋和執行。Dalvik類加載器使用mmap函數,將dex文件映射到內存中,經過普通的內存讀取操做便可訪問dex文件,而後解析dex文件內容並加載其中的類到哈希表中。bash

解析 dex

總的來講,dex文件能夠抽象爲三個部分:頭部、索引、數據。經過頭部能夠知道索引的位置和數目,以及數據區的起始位置。將dex文件映射到內存後,Dalvik會調用dexFileParse函數對其進行分析,分析的結果放到DexFile數據結構中。DexFile中的baseAddr指向映射區的起始位置,pClassDefs指向class索引的起始位置。爲了加快class的查找速度,還建立一個哈希表,對class名字進行哈希並生成索引。數據結構

加載 class

解析工做完成後就進行class的加載,加載的類須要用ClassObject數據結構來存儲。架構

typedef struct Object {
    ClassObject* clazz;  // 類型對象
    Lock lock;           // 鎖對象
} Object;
複製代碼

其中clazz指向ClassObject對象,還包含一個Lock對象。若是其它線程想要獲取它的鎖,只有等這個線程釋放。Dalvik每加載一個class都會對應一個ClassObject對象,加載過程會在內存中分配幾個區域,分別存放directMethodvirtualMethodsfieldifield。這些信息從dex文件的數據區中讀取。字段Field的定義以下:app

struct Field {
    ClassObject* clazz;    //所屬類型
    const char* name;      // 變量名稱
    const char* signature; // 如「Landroid/os/Debug;」
    u4 accessFlags;        // 訪問標記
    
    #ifdef PROFILE_FIELD_ACCESS
        u4 gets;
        u4 puts;
    #endif
};
複製代碼

待獲得class索引後,實際的加載由loadClassFromDex來完成。首先它會讀取class的具體數據,分別加載directMethodvirtualMethodifieldsfield,而後爲ClassObject數據結構分配內存,並讀取dex文件的相關信息。加載完成後,將加載的class經過dvmAddClassToHash函數放入哈希表,以方便下次查找;最後,經過dvmLinkClass查找該類的超類,若是有接口類則加載相應的接口類。函數

1.3.3 Dalvik 解釋器

對於任何虛擬機來講,解釋器無疑是核心的部分,全部的Java字節碼都通過解釋器解釋執行。因爲Dalvik解釋器的效率很重要,Android分別實現了C語言版和各類彙編語言版的解釋器。解釋器一般是循環執行,須要一個入口函數調用處理程序執行第一條指令,然後每條指令執行時引出下一條指令,經過函數指針調用處理程序。

2、Dalvik 虛擬機和 ART 虛擬機對比

Android 4.4以後,Google開始使用了更加優秀的ART虛擬機來替換Dalvik虛擬機,下面咱們就來對比一下這二者之間的區別。

2.1 Dalvik

打包的過程當中 會先將.java等源碼經過javac編譯成.class文件,再經過dx.class文件轉換成Dalvik虛擬機執行的.dex文件。

應用啓動的時候 先將.dex文件 轉換成機器碼,又由於65536的文件,致使在應用冷啓動的時候有一個合包的過程,最後的結果就是app的啓動時間有可能變慢,這就是Dalvik虛擬機的JIT(Just in Time)特性。

2.2 ART

ART除了兼容了Dalvik虛擬機的特性以外,還有一個很好的特性AOT(Ahead of Time),這個特性就是把 .dex 文件轉換成機器碼 這個步驟提早到了 應用安裝 的時候,ART虛擬機將.dex文件轉換成可直接運行的.oat文件,ART虛擬機天生支持多dex,因此也不會有一個合包的過程,所以會極大的提高APP冷啓動速度。

2.3 ART 虛擬機的優缺點

優勢:

  • 加快APP冷啓動速度
  • 提高GC速度
  • 提供功能全面的Debug特性

缺點:

  • APP安裝速度慢,由於在APK安裝的時候要生成可運行.oat文件
  • APK佔用空間大,由於在APK安裝的時候要生成可運行.oat文件

3、參考文獻

理解 Android 虛擬機體系結構 Android Dalvik 虛擬機和 ART 虛擬機對比

Dalvik 虛擬機簡要介紹和學習計劃 Dalvik 虛擬機的啓動過程分析 Dalvik 虛擬機的運行過程分析

深刻理解 Dalvik 虛擬機 - Android應用進程啓動過程分析 深刻理解 ART 虛擬機 - 虛擬機的啓動 深刻理解 ART 虛擬機 - ART 的函數運行機制 深刻理解 Dalvik 虛擬機 - 解釋器的運行機制 深刻理解ART虛擬機 - ImageSpace的加載過程分析


更多文章,歡迎訪問個人 Android 知識梳理系列:

相關文章
相關標籤/搜索