一、Dalvik 虛擬機器
Dalvik
是Google
公司自己設計用於Android
平臺的Java
虛擬機器,它是Android
平臺的重要組成部分,支援dex
格式的Java
應用程式的執行。
Dalvik
作為面向Linux
、為嵌入式作業系統設計的虛擬機器,主要負責完成 物件生命週期管理、堆疊管理、執行緒管理、安全和異常管理,以及垃圾回收等。Dalvik
充分利用Linux
程式管理的特定,對其進行了物件導向的設計,使得可以 同時執行多個程式,而傳統的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 檔案結構
.dex
檔案結構和.class
檔案結構差異的地方很多,但從攜帶的資訊上看,.dex
和.class
檔案是一致的:
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
裝置執行
1.3.2 Dalvik 類載入器
一個dex
檔案需要類載入器載入原生類和Java
類,然後通過直譯器根據指令集對Dalvik
位元組碼進行解釋和執行。Dalvik
類載入器使用mmap
函式,將dex
檔案對映到記憶體中,通過普通的記憶體讀取操作即可訪問dex
檔案,然後解析dex
檔案內容並載入其中的類到雜湊表中。
解析 dex
總的來說,dex
檔案可以抽象為三個部分:頭部、索引、資料。通過頭部可以知道索引的位置和數目,以及資料區的起始位置。將dex
檔案對映到記憶體後,Dalvik
會呼叫dexFileParse
函式對其進行分析,分析的結果放到DexFile
資料結構中。DexFile
中的baseAddr
指向對映區的起始位置,pClassDefs
指向class
索引的起始位置。為了加快class
的查詢速度,還建立一個雜湊表,對class
名字進行雜湊並生成索引。
載入 class
解析工作完成後就進行class的載入,載入的類需要用ClassObject
資料結構來儲存。
typedef struct Object {
ClassObject* clazz; // 型別物件
Lock lock; // 鎖物件
} Object;
複製程式碼
其中clazz
指向ClassObjec
t物件,還包含一個Lock
物件。如果其它執行緒想要獲取它的鎖,只有等這個執行緒釋放。Dalvik
每載入一個class
都會對應一個ClassObject
物件,載入過程會在記憶體中分配幾個區域,分別存放directMethod
、virtualMethod
、sfield
、ifield
。這些資訊從dex
檔案的資料區中讀取。欄位Field
的定義如下:
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
的具體資料,分別載入directMethod
、virtualMethod
、ifield
和sfield
,然後為ClassObject
資料結構分配記憶體,並讀取dex
檔案的相關資訊。載入完成後,將載入的class
通過dvmAddClassToHash
函式放入雜湊表,以方便下次查詢;最後,通過dvmLinkClass
查詢該類的超類,如果有介面類則載入相應的介面類。
1.3.3 Dalvik 直譯器
對於任何虛擬機器來說,直譯器無疑是核心的部分,所有的Java
位元組碼都經過直譯器解釋執行。由於Dalvik
直譯器的效率很重要,Android
分別實現了C
語言版和各種組合語言版的直譯器。直譯器通常是迴圈執行,需要一個入口函式呼叫處理程式執行第一條指令,而後每條指令執行時引出下一條指令,通過函式指標呼叫處理程式。
二、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
檔案
三、參考文獻
理解 Android 虛擬機器體系結構 Android Dalvik 虛擬機器和 ART 虛擬機器對比
Dalvik 虛擬機器簡要介紹和學習計劃 Dalvik 虛擬機器的啟動過程分析 Dalvik 虛擬機器的執行過程分析
深入理解 Dalvik 虛擬機器 - Android應用程式啟動過程分析 深入理解 ART 虛擬機器 - 虛擬機器的啟動 深入理解 ART 虛擬機器 - ART 的函式執行機制 深入理解 Dalvik 虛擬機器 - 直譯器的執行機制 深入理解ART虛擬機器 - ImageSpace的載入過程分析
更多文章,歡迎訪問我的 Android 知識梳理系列:
- Android 知識梳理目錄:www.jianshu.com/p/fd82d1899…
- Android 面試文件分享:www.jianshu.com/p/8456fe6b2…