本專欄專註分享大型Bat面試知識,後續會持續更新,喜歡的話麻煩點擊一個關注
廢話不多說先上面試目錄
Android開發中我們接觸的是與Java虛擬機類似的Dalvik虛擬機和ART虛擬機,下面梳理一下三者區別和原理:
一,Dalvik虛擬機 Dalvik虛擬機( Dalvik Virtual Machine ),簡稱Dalvik VM或者DVM。Dalvik 發音有道詞典並沒有收錄。說說來歷,它是由Dan Bornstein編寫的,名字源於他的祖先居住過的名為Dalvik的小漁村。DVM是Google專門為Android平臺開發的虛擬機,它運行在Android運行時庫中。需要注意的是DVM並不是一個Java虛擬機(以下簡稱JVM)
DVM之所以不是一個JVM ,主要原因是DVM並沒有遵循JVM規範來實現。DVM與JVM主要有以下區別。
基於的架構不同 JVM基於棧則意味著需要去棧中讀寫數據,所需的指令會更多,這樣會導致速度慢,對於性能有限的移動設備,顯然不是很適合。 DVM是基於寄存器的,它沒有基於棧的虛擬機在拷貝數據而使用的大量的出入棧指令,同時指令更緊湊更簡潔。但是由於顯示指定了操作數,所以基於寄存器的指令會比基於棧的指令要大,但是由於指令數量的減少,總的代碼數不會增加多少。
在Java SE程序中,Java類會被編譯成一個或多個.class文件,打包成jar文件,而後JVM會通過相應的.class文件和jar文件獲取相應的位元組碼。執行順序為: .java文件 -> .class文件 -> .jar文件 而DVM會用dx工具將所有的.class文件轉換為一個.dex文件,然後DVM會從該.dex文件讀取指令和數據。執行順序為: .java文件 –>.class文件-> .dex文件
如上圖所示,.jar文件裡麪包含多個.class文件,每個.class文件裡麪包含了該類的常量池、類信息、屬性等等。當JVM載入該.jar文件的時候,會載入裡面的所有的.class文件,JVM的這種載入方式很慢,對於內存有限的移動設備並不合適。 而在.apk文件中只包含了一個.dex文件,這個.dex文件裡面將所有的.class裡面所包含的信息全部整合在一起了,這樣再載入就提高了速度。.class文件存在很多的冗餘信息,dex工具會去除冗餘信息,並把所有的.class文件整合到.dex文件中,減少了I/O操作,提高了類的查找速度。
DVM經過優化,允許在有限的內存中同時運行多個進程。在Android中的每一個應用都運行在一個DVM實例中,每一個DVM實例都運行在一個獨立的進程空間。獨立的進程可以防止在虛擬機崩潰的時候所有程序都被關閉。
在Android系統啟動流程(二)解析Zygote進程啟動過程這篇文章中我介紹過 Zygote,可以稱它為孵化器,它是一個DVM進程,同時它也用來創建和初始化DVM實例。每當系統需要創建一個應用程序時,Zygote就會fock自身,快速的創建和初始化一個DVM實例,用於應用程序的運行。
DVM的源碼位於dalvik/目錄下,其中dalvik/vm目錄下的內容是DVM的具體實現部分,它會被編譯成libdvm.so;dalvik/libdex會被編譯成libdex.a靜態庫,作為dex工具使用;dalvik/dexdump是.dex文件的反編譯工具;DVM的可執行程序位於dalvik/dalvikvm中,將會被編譯成dalvikvm可執行程序。DVM架構如下圖所示。
從上圖可以看出,首先Java編譯器編譯的.class文件經過DX工具轉換為.dex文件,.dex文件由類載入器處理,接著解釋器根據指令集對Dalvik位元組碼進行解釋、執行,最後交與Linux處理。
DVM的運行時堆主要由兩個Space以及多個輔助數據結構組成,兩個Space分別是Zygote Space(Zygote Heap)和Allocation Space(Active Heap)。Zygote Space用來管理Zygote進程在啟動過程中預載入和創建的各種對象,Zygote Space中不會觸發GC,所有進程都共享該區域,比如系統資源。Allocation Space是在Zygote進程fork第一個子進程之前創建的,它是一種私有進程,Zygote進程和fock的子進程在Allocation Space上進行對象分配和釋放。
Card Table: 用於DVM Concurrent GC,當第一次進行垃圾標記後,記錄垃圾信息。 Heap Bitmap: 有兩個Heap Bitmap,一個用來記錄上次GC存活的對象,另一個用來記錄這次GC存活的對象。 Mark Stack: DVM的運行時堆使用標記-清除(Mark-Sweep)演算法進行GC,不瞭解標記-清除演算法的同學查看Java虛擬機(四)垃圾收集演算法這篇文章。Mark Stack就是在GC的標記階段使用的,它用來遍歷存活的對象。
ART(Android Runtime)是Android 4.4發布的,用來替換Dalvik虛擬,Android 4.4默認採用的還是DVM,系統會提供一個選項來開啟ART。在Android 5.0時,默認採用ART,DVM從此退出歷史舞臺。
2.除了這四個Space,ART的Java堆中還包括兩個Mod Union Table,一個Card Table,兩個Heap Bitmap,兩個Object Map,以及三個Object Stack
福利時間:
領取如下資料:
Android架構進階學習資源資料免費獲取