Android面試收集錄13 Android虛擬機及編譯過程

 

1、什麼是Dalvik虛擬機

Dalvik是Google公司本身設計用於Android平臺的Java虛擬機,它是Android平臺的重要組成部分,支持dex格式(Dalvik Executable)的Java應用程序的運行。dex格式是專門爲Dalvik設計的一種壓縮格式,適合內存和處理器速度有限的系統。Google對其進行了特定的優化,使得Dalvik具備高效、簡潔、節省資源的特色。從Android系統架構圖知,Dalvik虛擬機運行在Android的運行時庫層。java

Dalvik做爲面向Linux、爲嵌入式操做系統設計的虛擬機,主要負責完成對象生命週期管理、堆棧管理、線程管理、安全和異常管理,以及垃圾回收等。另外,Dalvik早期並無JIT編譯器,直到Android2.2才加入了對JIT的技術支持。android

 

 

2、Dalvik虛擬機的特色

體積小,佔用內存空間小;git

專有的DEX可執行文件格式,體積更小,執行速度更快;github

常量池採用32位索引值,尋址類方法名,字段名,常量更快;算法

基於寄存器架構,並擁有一套完整的指令系統;安全

提供了對象生命週期管理,堆棧管理,線程管理,安全和異常管理以及垃圾回收等重要功能;架構

全部的Android程序都運行在Android系統進程裏,每一個進程對應着一個Dalvik虛擬機實例。併發

 

 

3、Dalvik虛擬機和Java虛擬機的區別

Dalvik虛擬機與傳統的Java虛擬機有着許多不一樣點,二者並不兼容,它們顯著的不一樣點主要表如今如下幾個方面:app

Java虛擬機運行的是Java字節碼,Dalvik虛擬機運行的是Dalvik字節碼。工具

傳統的Java程序通過編譯,生成Java字節碼保存在class文件中,Java虛擬機經過解碼class文件中的內容來運行程序。而Dalvik虛擬機運行的是Dalvik字節碼,全部的Dalvik字節碼由Java字節碼轉換而來,並被打包到一個DEX(Dalvik Executable)可執行文件中。Dalvik虛擬機經過解釋DEX文件來執行這些字節碼。

img

Dalvik可執行文件體積小。Android SDK中有一個叫dx的工具負責將Java字節碼轉換爲Dalvik字節碼。

dx工具對Java類文件從新排列,消除在類文件中出現的全部冗餘信息,避免虛擬機在初始化時出現反覆的文件加載與解析過程。通常狀況下,Java類文件中包含多個不一樣的方法簽名,若是其餘的類文件引用該類文件中的方法,方法簽名也會被複制到其類文件中,也就是說,多個不一樣的類會同時包含相同的方法簽名,一樣地,大量的字符串常量在多個類文件中也被重複使用。這些冗餘信息會直接增長文件的體積,同時也會嚴重影響虛擬機解析文件的效率。消除其中的冗餘信息,從新組合造成一個常量池,全部的類文件共享同一個常量池。因爲dx工具對常量池的壓縮,使得相同的字符串,常量在DEX文件中只出現一次,從而減少了文件的體積。

針對每一個Class文件,都由以下格式進行組成:

img

dex格式文件使用共享的、特定類型的常量池機制來節省內存。常量池存儲類中的全部字面常量,它包括字符串常量、字段常量等值。

img

簡單來說,dex格式文件就是將多個class文件中公有的部分統一存放,去除冗餘信息。

**Java虛擬機與Dalvik虛擬機架構不一樣。**這也是Dalvik與JVM之間最大的區別。

Java虛擬機基於棧架構,程序在運行時虛擬機須要頻繁的從棧上讀取或寫入數據,這個過程須要更多的指令分派與內存訪問次數,會耗費很多CPU時間,對於像手機設備資源有限的設備來講,這是至關大的一筆開銷。Dalvik虛擬機基於寄存器架構。數據的訪問經過寄存器間直接傳遞,這樣的訪問方式比基於棧方式要快不少。

 

4、Dalvik虛擬機的結構

img

一個應用首先通過DX工具將class文件轉換成Dalvik虛擬機能夠執行的dex文件,而後由類加載器加載原生類和Java類,接着由解釋器根據指令集對Dalvik字節碼進行解釋、執行。最後,根據dvm_arch參數選擇編譯的目標機體系結構。

 

5、Android APK 編譯打包流程

img

1.Java編譯器對工程自己的java代碼進行編譯,這些java代碼有三個來源:app的源代碼,由資源文件生成的R文件(aapt工具),以及有aidl文件生成的java接口文件(aidl工具)。產出爲.class文件。

①.用AAPT編譯R.java文件

②編譯AIDL的java文件

③把java文件編譯成class文件

2..class文件和依賴的三方庫文件經過dex工具生成Delvik虛擬機可執行的.dex文件,包含了全部的class信息,包括項目自身的class和依賴的class。產出爲.dex文件。

3.apkbuilder工具將.dex文件和編譯後的資源文件生成未經簽名對齊的apk文件。這裏編譯後的資源文件包括兩部分,一是由aapt編譯產生的編譯後的資源文件,二是依賴的三方庫裏的資源文件。產出爲未經簽名的.apk文件。

4.分別由Jarsigner和zipalign對apk文件進行簽名和對齊,生成最終的apk文件。

總結爲:編譯-->DEX-->打包-->簽名和對齊

 

6、ART虛擬機與Dalvik虛擬機的區別

什麼是ART:

ART表明Android Runtime,其處理應用程序執行的方式徹底不一樣於Dalvik,Dalvik是依靠一個Just-In-Time (JIT)編譯器去解釋字節碼。開發者編譯後的應用代碼須要經過一個解釋器在用戶的設備上運行,這一機制並不高效,但讓應用能更容易在不一樣硬件和架構上運 行。ART則徹底改變了這套作法,在應用安裝時就預編譯字節碼到機器語言,這一機制叫Ahead-Of-Time (AOT)編譯。在移除解釋代碼這一過程後,應用程序執行將更有效率,啓動更快。

ART優勢:

  1. 系統性能的顯著提高。
  2. 應用啓動更快、運行更快、體驗更流暢、觸感反饋更及時。
  3. 更長的電池續航能力。
  4. 支持更低的硬件。

ART缺點:

  1. 更大的存儲空間佔用,可能會增長10%-20%。
  2. 更長的應用安裝時間。

ART虛擬機相對於Dalvik虛擬機的提高

預編譯

在dalvik中,如同其餘大多數JVM同樣,都採用的是JIT來作及時翻譯(動態翻譯),將dex或odex中並排的dalvik code(或者叫smali指令集)運行態翻譯成native code去執行.JIT的引入使得dalvik提高了3~6倍的性能。

而在ART中,徹底拋棄了dalvik的JIT,使用了AOT直接在安裝時將其徹底翻譯成native code.這一技術的引入,使得虛擬機執行指令的速度又一重大提高

垃圾回收機制

首先介紹下dalvik的GC的過程.主要有有四個過程:

  1. 當gc被觸發時候,其會去查找全部活動的對象,這個時候整個程序與虛擬機內部的全部線程就會掛起,這樣目的是在較少的堆棧裏找到所引用的對象.須要注意的是這個回收動做和應用程序非併發。
  2. gc對符合條件的對象進行標記
  3. gc對標記的對象進行回收
  4. 恢復全部線程的執行現場繼續運行

dalvik這麼作的好處是,當pause了以後,GC勢必是至關快速的.可是若是出現GC頻繁而且內存吃緊勢必會致使UI卡頓,掉幀.操做不流暢等。

後來ART改善了這種GC方式 , 主要的改善點在將其非併發過程改變成了部分併發.還有就是對內存的從新分配管理。

當ART GC發生時:

  1. GC將會鎖住Java堆,掃描並進行標記
  2. 標記完畢釋放掉Java堆的鎖,而且掛起全部線程
  3. GC對標記的對象進行回收
  4. 恢復全部線程的執行現場繼續運行
  5. 重複2-4直到結束

能夠看出整個過程作到了部分併發使得時間縮短.據官方測試數聽說gc效率提升2倍

提升內存使用,減小碎片化

Dalvik內存管理特色是:內存碎片化嚴重,固然這也是Mark and Sweep算法帶來的弊端

img

能夠看出每次gc後內存千瘡百孔,原本連續分配的內存塊變得碎片化嚴重,以後再分配進入的對象再進行內存尋址變得困難。

ART的解決:在ART中,它將Java分了一塊空間命名爲Large-Object-Space,這塊內存空間的引入用來專門存放large object。同時ART又引入了moving collector的技術,即將不連續的物理內存塊進行對齊.對齊了後內存碎片化就獲得了很好的解決.Large-Object-Space的引入一是由於moving collector對大塊內存的位移時間成本過高,並且提升內存的利用率 根官方統計,ART的內存利用率提升10倍了左右。

 

7、參考文章

  https://github.com/LRH1993/android_interview/blob/master/android/basis/dalvik-art.md

相關文章
相關標籤/搜索