小白理解安卓虛擬機以及華爲的'諾亞方舟'

虛擬機,提到虛擬機,你們可能第一反應就是java中好像有虛擬機這個玩意。可是安卓中的虛擬機是什麼呢?是和java同樣的嗎?那麼咱們先來了解一下java中的JVM!

JVM,搞java的確定對它瞭解很多。JVM本質上就是一個軟件,是計算機硬件的一層軟件抽象,在這之上才幹夠運行Java程序,JAVA在編譯後會生成類似於彙編語言的JVM字節碼,與C語言編譯後產生的彙編語言不一樣的是,C編譯成的彙編語言會直接在硬件上跑。但JAVA編譯後生成的字節碼是在JVM上跑,需要由JVM把字節碼翻譯成機器指令。才幹使JAVA程序跑起來。JVM運行在操做系統上,屏蔽了底層實現的差別。從而有了JAVA吹噓的平臺獨立性和Write Once Run Anywhere。依據JVM規範實現的詳細虛擬機有幾十種,主流的JVM包括Hotspot、Jikes RVM等。都是用C/C++和彙編編寫的,每個JRE編譯的時候針對每個平臺編譯。所以下載JRE(JVM、Java核心類庫和支持文件)的時候是分平臺的,JVM的做用是把平臺無關的.class裏面的字節碼翻譯成平臺相關的機器碼,來實現跨平臺。java

說白了,簡單點,就是:android

                                                                      Java算法

                                                                      .java文件 -> .class文件 -> .jar文件網絡

最後執行是class文件,有的會被再次打包成jar文件。jvm

瞭解了這些以後,咱們再去了解Android 中的虛擬機。ide

1、Dalvik虛擬機

Dalvik虛擬機( Dalvik Virtual Machine ),簡稱Dalvik VM或者DVM。這就是Android中的虛擬機。最初它的產生,是由於Google爲了解決與Oracle之間關於Java相關專利和受權的糾紛,開發了DVM。函數

Android既然存在虛擬機,確定也是在這個DVM上執行的。它的執行流程和JVM很像:工具

                                                                       Android性能

                                                                      .java文件 –> .class文件 -> .dex文件->.apk優化

DVM執行的是.dex格式文件,JVM執行的是.class文件,android程序編譯完以後生產.class文件,而後,dex工具會把.class文件處理成.dex文件,而後把資源文件和.dex文件等打包成.apk文件,apk就是android package的意思。

除了上面所說的,專利受權的緣由除外,其實還有由於以下緣由:

    dvm是基於寄存器的虛擬機,而jvm是基於虛擬棧的虛擬機。寄存器存取速度比棧快得多,dvm能夠根據硬件實現最大的優化,比較適合移動設備。

    class文件存在不少的冗餘信息,dex工具會去除冗餘信息,並把全部的.class文件整合到.dex文件中,減小了I/O操做,提升了類的查找速度。

不光是上面這些差別,還有運行環境。  

   Dalvik : 一個應用啓動都運行一個單獨的虛擬機運行在一個單獨的進程中

   JVM: 只能運行一個實例, 也就是全部應用都運行在同一個JVM中

 

 這個是早先的安卓虛擬機,運行速度仍是至關慢的。基於寄存器的虛擬機容許更快的執行時間,但代價是編譯後的程序更大。因而新的Dex字節碼格式odex產生了。它的做用等同於dex,只不過是dex優化後的格式。在App安裝的過程當中,會經過Socket向/system/bin/install進程發送dex_opt的指令,對Dex文件進行優化。在DexClassLoader動態加載Dex文件時,也會進行Dex的優化,造成odex文件。

 

爲了適應硬件速度的提高,隨後在Android 2.2的DVM中加入了JIT 編譯器(Just-In-Time Compiler)。Dalvik 使用 JIT 進行即時編譯,藉助 Java HotSpot VM,JIT 編譯器能夠對執行次數頻繁的 dex/odex 代碼進行編譯與優化,將 dex/odex 中的 Dalvik Code(Smali 指令集)翻譯成至關精簡的 Native Code 去執行,JIT 的引入使得 Dalvik 的性能提高了 3~6 倍。

JIT編譯器的引入,提高了安裝速度,減小了佔用的空間,但隨之帶來的問題就是:多個dex加載會很是慢;JIT中的解釋器解釋的字節碼會帶來CPU和時間的消耗;還有熱點代碼的Monitor一直在運行帶來電量的損耗。

 

 這種狀況下,手機動不動就卡是難以免的。相信各位若是那時候用着Android手機,必定印象很是深入。由於並非那麼好用。

這樣的情況一直持續到Andorid 4.4,帶來了全新的虛擬機運行環境 ART(Android RunTime)的預覽版和全新的編譯策略 AOT(Ahead-of-time)。但那時候。 ART 是和 Dalvik 共存的,用戶能夠在二者之間進行選擇(感受很奇怪,做爲一個愛好者,我當時看到這個東西能夠切換都是不曉得是什麼玩意,用戶可都是小白啊,沒有必要共存的吧)。在Android 5.0的時候,ART 全面取代 Dalvik 成爲 Android 虛擬機運行環境,至此。Dalvik 退出歷史舞臺,AOT 也成爲惟一的編譯模式。

2、ART 

AOT 和 JIT 的不一樣之處在於:JIT 是在運行時進行編譯,是動態編譯,而且每次運行程序的時候都須要對 odex 從新進行編譯;而 AOT 是靜態編譯,應用在安裝的時候會啓動 dex2oat 經過靜態編譯的方式,來將全部的dex文件(包括Multidex)編譯oat文件,編譯完後的oat實際上是一個標準的ELF文件,只是相對於普通的ELF文件多加了oat data section以及oat exec section這兩個段而已。(這兩個段裏面主要保存了兩種信息:Dex的文件信息以及類信息和Dex文件編譯以後的機器碼)。預編譯成 ELF 文件,每次運行程序的時候不用從新編譯,是真正意義上的本地應用。運行的文件格式也從odex轉換成了oat格式。

 

其實在Android5.0的時候咱們可以明顯感受手機好用不少就是由於這個緣由,從根本上換掉了那種存在着沒法解決弊端的虛擬機。在 Android 5.x 和 6.x 的機器上,系統每次 OTA 升級完成重啓的時候都會有個應用優化的過程,這個過程就是剛纔所說的 dex2oat 過程,這個過程比較耗時而且會佔用額外的存儲空間。

AOT 模式的預編譯解決了應用啓動和運行速度和耗資源(電等)問題的同時也帶來了另外兩個問題:

      一、應用安裝和系統升級以後的應用優化比較耗時,而且會更耗時間。由於系統和apk都是愈來愈大的。

      二、優化後的文件會佔用額外的存儲空間

在通過了兩個Android大版本的穩定後,在Android7.0又再次迎來了JIT的 迴歸。

JIT的迴歸,可不是把AOT模式給取代了,而是造成 了AOT/JIT 混合編譯模式,這種模式至今仍在使用

應用在安裝的時候 dex 不會被編譯。

應用在運行時 dex 文件先經過解析器(Interpreter)後會被直接執行(這一步驟跟 Android 2.2 - Android 4.4以前的行爲一致),與此同時,熱點函數(Hot Code)會被識別並被 JIT 編譯後存儲在 jit code cache 中並生成 profile 文件以記錄熱點函數的信息。

手機進入 IDLE(空閒) 或者 Charging(充電) 狀態的時候,系統會掃描 App 目錄下的 profile 文件並執行 AOT 過程進行編譯。

(Profile文件會在JIT運行的過程當中生成:每一個APP都會有本身的Profile文件,保存在App自己的Local Storage中。Profile會保存所調用的類以及函數的Index,經過profman工具進行分析生成)

 

 

我的理解:哪一種模式擅長幹什麼就讓他去幹什麼。

混合編譯模式綜合了 AOT 和 JIT 的各類優勢,使得應用在安裝速度加快的同時,運行速度、存儲空間和耗電量等指標都獲得了優化。

以前一直在說流暢,真的流暢在Android7.0上才感覺到了些許。Android7.0系統也被用了至關長的一段時間。以後的Android8.0和Android9.0都是對各方面的優化,例如編譯文件、編譯器、GC。。

其中,值得一提的是華爲的方舟編譯器。

  • 首先會判斷該設備支不支持方舟編譯器,若是支持,則從應用商店下發方舟版本的包
  • 方舟編譯器會把dex文件經過本身的IR翻譯方舟格式的機器碼,據資料說也是一個ELF文件,可是會增長一些段,猜想是Dex中類信息相關的段
  • 經過這種方式,來消除Java與JNI之間的通訊的損耗,以及提高運行時的效率
  • 在方舟內部,還從新完善了GC算法,使得GC的頻率大大下降,減小應用卡頓的現象
  • 目前方舟只支持64位的So,而且對於加殼的So會出現一些問題。

方舟編譯器適配的應用,下載手機上都是方舟版本的包,特製的包用方舟編譯器編譯效率大大提高,以後直接執行就能夠了,直接略過了在ART虛擬機上預編譯的過程。這樣的結果是很完美的,可是卻也沒辦法跳過一個弊端。那就是生態。仍是無論是安卓仍是iOS,這麼多年的時間沉澱中,他們的生態系統早就達到了一個很是完善的地步。安卓和iOS應用已經多達上千萬,而方舟適配應用的數量還很是有限。

谷歌宣佈將中止對華爲提供安卓系統更新以後,華爲曝光了自主研發的鴻蒙操做系統。當時網友各類力挺。不事後來,華爲董事長梁華在談及鴻蒙系統時稱,鴻蒙系統是爲物聯網開發的,用於自動駕駛、遠程醫療等低時延場景。鴻蒙系統是否是兩手準備咱們不得而知。可是,一個操做系統最重要的就是它的生態環境。縱觀華爲如今的整個格局,目的很是明確,用方舟編譯器來擴大本身的用戶羣體。當用戶的基數足夠龐大時,能夠隨時隨地創建一個完善的生態系統。若是在將來某一天,Android全面限制華爲的使用以後,在這危機關頭鴻蒙系統仍是頗有可能扛起國產手機的一面大旗。哪怕不是鴻蒙,咱們也須要這樣一個生態不是嗎?

最初,忽然去了解Android中的虛擬機,一個是想要明白到底Android中的虛擬機和JVM是否是一回事,還有就是想要明白華爲發佈方舟編譯器到底快到了哪裏。

上述相關資料均來自網絡,侵權必刪。

相關文章
相關標籤/搜索