從JVM到Dalivk再到ART(class,dex,odex,ELF)

個人博客地址 http://dandanlove.com/

現在市面上的Android手機大部分都是運行的是ART虛擬機了。還記得自己一部Android手機(HUWEIg520),Android4.1系統。那時候還是沒有ART虛擬機的。作爲Android開發者,我們應該對Android的發展歷史有些瞭解爲什麼Android會經歷這麼多的變化。Android是先有JVM然後是Dalvik,接着是現在的ART虛擬機。那麼他們之間有什麼關係呢?

JVM就不用講述了大家都有了解,不瞭解的參見JVM百度百科

Dalvik是Google公司自己設計用於Android平臺的虛擬機,是Google等廠商合作開發的Android移動設備平臺的核心組成部分之一。它可以支持已轉換爲 .dex格式的Java應用程序的運行,.dex格式是專爲Dalvik設計的一種壓縮格式,適合內存和處理器速度有限的系統。

Dalvik和JVM的主要區別

首先通過介紹Dalvik的時候我們就知道Dalvik運行的是dex文件,而JVM運行的是class文件。

Dalvik VM是基於寄存器的架構,而JVM是棧機。所以Dalvik VM的好處是可以做到更好的提前優化(ahead-of-time optimization)。 另外基於寄存器架構的VM執行起來更快,但是代價是更大的代碼長度。
~~
基於寄存器架構的虛擬機有這麼多的好處,爲什麼之前設計JAVA的程序員沒有采用呢,而是採用現在基於棧的架構開發的呢?因爲基於棧的虛擬機也有它的優點,它不對host平臺的寄存器數量做假設,有利於移植到不懂的平臺,這也符合的Java跨平臺的特點。而Dalvik虛擬機則不關心這些,因爲它本來就是爲ARM這樣的多寄存器平臺設計的,另外Dalvik被移植到x86機器上,即使x86這種寄存器少的平臺,寄存器架構的虛擬機也可以運行。
~~
一般來說,基於堆棧的機器必須使用指令才能從堆棧上的加載和操作數據,因此,相對基於寄存器的機器,它們需要更多的指令才能實現相同的性能。但是基於寄存器機器上的指令必須經過編碼,因此,它們的指令往往更大。

public class Demo {
    public static void foo() {
        int a = 1;
        int b = 2;
        int c = (a + b) * 5;
     } 
}

我們可以查看Demo.java在JVM中的class和Dalvik的dex字節碼文件:
詳見:使用dx將class轉dex總結

想要了解更多:基於棧的虛擬機 VS 基於寄存器的虛擬機

Dalvik在JVM上的優化

  • 在編譯時提前優化代碼而不是等到運行時
  • 虛擬機很小,使用的空間也小;被設計來滿足可高效運行多種虛擬機實例。
  • 常量池已被修改爲只使用32位的索引,以簡化解釋器
  • 標準Java字節碼實行8位堆棧指令,Dalvik使用16位指令集直接作用於局部變量。局部變量通常來自4位的“虛擬寄存器”區。這樣減少了Dalvik的指令計數,提高了翻譯速度。

在這裏插入圖片描述

Dalivk進化之ART

2014年6月25日,Android L 正式亮相於召開的谷歌I/O大會,Android L 改動幅度較大,谷歌將直接刪除Dalvik,代替它的是傳聞已久的ART。

ART:即Android Runtime
ART 的機制與 Dalvik 不同。在Dalvik下,應用每次運行的時候,字節碼都需要通過即時編譯器(just in time ,JIT)轉換爲機器碼,這會拖慢應用的運行效率,而在ART 環境中,應用在第一次安裝的時候,字節碼就會預先編譯成機器碼,使其成爲真正的本地應用。這個過程叫做預編譯(AOT,Ahead-Of-Time)。這樣的話,應用的啓動(首次)和執行都會變得更加快速。

ART的優缺點

優點:

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

缺點:

  • 機器碼佔用的存儲空間更大,字節碼變爲機器碼之後,可能會增加10%-20%(不過在應用包中,可執行的代碼常常只是一部分。比如最新的 Google+ APK 是 28.3 MB,但是代碼只有 6.9 MB。)
  • 應用的安裝時間會變長。

class、dex、odex、ELF相愛相殺

從執行文件上面進行分析的話,JVM對應class文件,Dalivk對應odex文件,而ART對應dex文件。

爲了在JVM優化出一個Dalivk虛擬機,所以把JVM運行的class文件進行打包優化爲dex文件,但其本質還是和class文件一樣屬於字節碼文件。但是爲了每次啓動時都去掉從字節碼到機器碼的編譯過程,Google又從Dalivk中優化出了ART,在其安裝應用的時候將dex文件進行預處理生成可執行的oat文件。

JIT的引入

據說Android 2.2的虛擬機dalvik使用了JIT技術,使其運行速度快了5倍。dalvik解釋並執行程序,JIT技術主要是對多次運行的代碼進行編譯,當再次調用時使用編譯之後的機器碼,而不是每次都解釋,以節約時間。5倍是測試程序測出的值,並不是說程序運行速度也能達到5倍,這是因爲測試程序有很多的重複調用和循環,而一般程序主要是順序執行的,而且它是一邊運行,一邊編譯,一開始的時候提速不多,所以真正運行程序速度提高不是特別明顯。

每啓動一個應用程序,都會相應地啓動一個dalvik虛擬機,啓動時會建立JIT線程,一直在後臺運行。當某段代碼被調用時,虛擬機會判斷它是否需要編譯成機器碼,如果需要,就做一個標記,JIT線程不斷判斷此標記,如果發現被設定就把它編譯成機器碼,並將其機器碼地址及相關信息放入entry table中,下次執行到此就跳到機器碼段執行,而不再解釋執行,從而提高速度。

Odex

因爲apk實際爲zip壓縮包,虛擬機每次加載都需要從apk中讀取classes.dex文件,這樣會耗費很多的時間,而如果採用了odex方式優化的dex文件,他包含了加載dex必須的依賴庫文件列表,只需要直接加載而不需要再去解析。

AOT(Ahead-of-time)

ART 推出了預先 (AOT) 編譯,可提高應用的性能。ART 還具有比 Dalvik 更嚴格的安裝時驗證。在安裝時,ART 使用設備自帶的 dex2oat 工具來編譯應用。該實用工具接受 DEX 文件作爲輸入,並針對目標設備生成已編譯應用的可執行文件。之後打開App的時候,不需要額外的翻譯工作,直接使用本地機器碼運行,因此運行速度提高。

ELF文件

ELF(Executable and Linking Format)是一種對象文件的格式,用於定義不同類型的對象文件(Object files)中都放了什麼東西、以及都以什麼樣的格式去放這些東西。它自最早在 System V 系統上出現後,被 xNIX 世界所廣泛接受,作爲缺省的二進制文件格式來使用。可以說,ELF是構成衆多xNIX系統的基礎之一。

文中部分內容摘自:
深入理解JVM-字節碼執行引擎
Android 中的Dalvik和ART是什麼,有啥區別?
知乎-Dalvik 虛擬機和 Sun JVM 在架構和執行方面有什麼本質區別?
《Java虛擬機原理圖解》4.JVM機器指令集

文章到這裏就全部講述完啦,若有其他需要交流的可以留言哦

想閱讀作者的更多文章,可以查看我 個人博客 和公共號:
振興書城

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章