前言html
轉載請聲明,轉自【http://www.javashuo.com/article/p-eojuwqrv-gq.html】,謝謝!java
Android虛擬機的使用,使得android應用和Linux內核分離,這樣作使得android系統更穩定可靠,好比程序中即便包含惡意代碼,也不會直接影響系統文件;也提升了跨平臺兼容性。在Android4.4之前的系統中,Android系統均採用Dalvik做爲運行andorid程序的虛擬機,在android發展中具備舉足輕重的地位,而Android 5.0及之後的系統使用ART虛擬機取代Dalvik,在性能上作了很大的優化。本文將對這兩款虛擬機作一些介紹,主要內容以下:android
閱讀本文,建議結合筆者以前的兩篇文章,瞭解一下JVM和Apk打包:安全
1、什麼是Dalvik?ide
Dalvik是Google公司本身設計用於Android平臺的虛擬機,是Android移動設備平臺的核心組成部分之一。虛擬機的概念在前面文章中講到過是,就是一個設備上開闢的一個虛擬空間,一個虛擬出來的設備。Dalvik就是這樣,在android設備上虛擬出來的一個用於運行Android程序的空間。因爲Android程序的開發語言是java,因此Dalvik的本質仍然是JVM,是一個特殊設計的JVM,沒有遵循Java虛擬機規範。另外,值得一提的是,Dalvik的命名來源於其祖先生活在冰島的一個叫作Dalvik的小漁村。工具
2、Dalvik在Android架構中所處的位置post
想必讀者們對如上截圖已經至關熟悉了——android系統架構圖。從上圖能夠看到,Dalvik虛擬機在Android Runtime中,在Linux Kernel之上。咱們都知道,Android其實就是一個操做系統,其底層基於Linxu Kernel,這一層有許多的驅動程序,主要完成操做系統所具有的功能。Android Runtime,即android的運行環境,咱們能夠類比於java的jre,即java平臺運行期環境。Java程序的開發、編譯和運行須要java的核心包(jdk/lib/和jre/lib)支持,而後經過JVM來運行java程序,一樣android程序的運行也是如此,Libraries就至關於java的jdk/lib,是開發/編譯android程序所須要的庫,Android Runtime裏面的Core Libraries裏就至關於java的jre/lib,是運行android程序所須要的核心庫,天然而然,Dalvik虛擬機也就類比於java中的JVM,用於運行android程序。性能
3、Dalvik的做用
簡單來講就是:Dalvik虛擬機在Android操做系統上虛擬出一個設備,用來運行android 應用程序。Dalvik是apk運行的溫牀,其做爲面向Linux、爲嵌入式操做系統特別設計的虛擬機, 主要負責完成對象的生命週期管理、堆棧管理、線程管理、安全及異常管理、垃圾回收等。Dalvik充分利用Linux進程管理的特性,對其進項了面向對象的設計,使得能夠同時運行多個程序,而傳統的Java程序一般只能運行一個進程,這也是爲何Android不採用JVM的緣由之一。在Android中,每個app進程對應一個Dalvik,多個app進程在運行,就對應多個虛擬機的存在,這樣設計的好處就是,當一個應用crash後,只會影響本身所在的dalvik,而不會影響到整個系統,不一樣的進程之間(即不一樣的Dalvik之間)經過進程間通訊來實現交互。
4、Dalvik和JVM的區別與聯繫
Android程序也是用Java語言開發的,因此Dalvik本質上講也是java虛擬機,那麼Dalvik和JVM又有哪些區別和聯繫呢?主要有以下幾點:
(1)本質上Dalvik也是JVM,是特殊設計的JVM,沒有遵循java虛擬機設計規範。
(2)JVM是基於棧的虛擬機,而Dalvik是基於寄存器的虛擬機,對於基於棧和基於寄存器的虛擬機的區別和優缺點,推薦閱讀:基於棧虛擬機和基於寄存器虛擬機的比較,講的簡潔且易懂,我們這裏不深刻展開。
(3)JVM運行的是Java字節碼文件,即.class文件,而Dalvik運行的是.dex(即Dalvik Executable)文件。.dex是在.class文件的基礎上,通過DEX工具壓縮和優化後造成的。以下圖所示:
當javac將java程序編譯成class後,dex工具將全部的class文件整合到一個.dex文件中,這樣作使得各個類可以共享數據,在必定程度上下降了冗餘,同時也使文結構更加緊湊。.dex格式也是專爲Dalvik設計的一種壓縮格式,適合內存和處理器速度有限的系統。實驗代表,dex文件時傳統jar文件的50%左右。下圖爲java .jar包中.class文件和android .apk中.dex文件對比圖:
(4)補充兩個Davik的特徵:
1)Dalvik通過優化,容許在有限的內存中同時運行多個虛擬機的實例,每個應用對應一個虛擬機實例,對應了一個進程,對應一個獨立的Linux進程。獨立的進程能夠防止在虛擬機崩潰的時候全部程序都被關閉。
2)Dalvik第一次加載後,會生成Cache文件,以提供下次快速加載,因此第一次會很慢。
5、Davik的孵化器——Zygote進程
在Android系統中有個一特殊的虛擬機進程Zygote,他是虛擬機實例的孵化器。它在系統啓動的時候就會產生,完成虛擬機的初始化、庫的加載、預製類庫和初始化操做。若是系統須要一個新的虛擬機實例,他會迅速複製自身,以最快的速度提供給系統。對於一些只讀的系統庫,全部的虛擬機實例都和Zygote共享一塊區域。
6、Dalvik的致命缺點:拖慢Android系統速度
Dalvik有個致命的弱點,就是Dalvik虛擬機一直被用戶指責爲拖慢Android系統運行速度而不如IOS的根源。主要緣由以下:
一、開發者因素
Android起步比IOS晚,平臺不成熟,初期開發者水平有限,對性能方面關注比較少,主要關注點在提供各類豐富多彩的應用上。
二、運營商因素
Android是開源的,不一樣的手機廠商每每對android系統進行定製,而各廠商的技術良莠不齊,修改後的特性或新增的功能,對原生系統的性能也形成必定的影響。同時,Android比較開放,有些開發者不顧用戶體驗,爲一些目的在後臺作了一些小動做,好比收集用戶信息等,拖慢總體速度。
三、Dalvik運行時機制因素
在編譯Android程序的時候,首先java代碼被編譯成class文件,而後被java打包工具dx打包成.dex文件,而後.dex文件和資源文件一塊兒被壓縮成apk文件。Apk文件其實也是zip格式,只是後綴被修改成apk,讀者能夠本身解壓一個apk試試看。Android應用的安裝過程:複製apk安裝包到data/app目錄(見截圖6.3.2,截圖6.3.3)下,解壓並掃描安裝包,把dex文件保存到dalvik-cache目錄(見截圖6.3.4)下,並在data/data(見截圖6.3.5)目錄下建立對應的應用數據目錄。這樣每次用戶點擊圖標運行android程序時,dalvik虛擬機就會用JIT(Android2.2及之後版本)的方法把dex文件翻譯爲機器碼,而後再執行機器碼。雖然Dalvik虛擬機已經被作過不少優化(.dex文件基礎上被優化爲.odex文件,o表示optimization,「優化」的意思),但由於此種機制的存在,先翻譯再執行,因此Android在電量消耗和程序運行流暢程度上一直不太理想。
截圖6.3.1 Android中 /data目錄
截圖6.3.2 /data/app目錄
截圖6.3.3 /data/app目錄下應用的信息
截圖6.3.4 /data/dalvik-cache目錄下的內容
截圖6.3.5 /data/data目錄下應用數據目錄,存儲對應應用運行中產生的一些數據
7、ART虛擬機取代Dalvik虛擬機
在第六點中,咱們講到了,因爲Dalvik虛擬機機制的問題,拖慢了android應用的速度。由此,ART(即Android RunTime)虛擬機應運而生,在Android4.4中能夠在設置中切換選擇Dalvik或ART做爲虛擬機,在Android L(5.0)中就直接刪除了Dalvik,而全面使用ART。ART在機制上作了優化,能夠在第一次安裝應用時,字節碼就會預編譯(即AOT編譯:Ahead-of-time)成機器碼,使其成爲真正的本地應用。在點擊桌面的應用圖標運行時,無需再翻譯字節碼,而是直接運行機器碼,從而提高了啓動速度。另外,ART在英語單詞中是「藝術」的意思,可見,ART虛擬機的設計是匠心獨運,同時也是被其設計中所高度讚譽的。
下圖展現了Dalvik和ART對.dex文件的處理的對比狀況:
8、ART的優缺點
一、優勢
ART的AOT方式相比於Dalvik的JIT方式(Just-In-Time,即時編譯,,參見JIT_百度百科),主要由以下的有優點:
(1)ART拋棄了Dalvik的JIT方式,而採用AOT預編譯方式,在安裝apk的過程當中,將.odex文件(.dex優化後的文件)預編譯爲二進制機器碼,存儲在設備中,之後每次啓動應用的時候,直接運行機器碼,而無需再翻譯.odex,這樣極大地提升了應用的啓動速度。
(2)每次運行時所作的工做也少了,這樣佔用了更少的CPU資源,也消耗了更少的電池資源。
(3)ART也在開發者工具和垃圾回收器上作了改善。
Dalvik和ART在性能上的對比
二、缺點
硬幣有正反面,ART的預編譯,也帶來了必定的劣勢
(1)增長了安裝時間。在安裝的時候須要預編譯,無疑增大了安裝的工做量,從而增大了安裝時間,對於一些大的應用,可能須要幾分鐘的時間才能安裝完。
(2)須要更多的空間存儲預編譯後的機器碼,無疑佔用了更多的存儲空間。固然,如今硬件設備更新換代很快,性能也很是好,相比於ART帶來的優勢,該缺點幾乎沒什麼影響。
9、Android N對ART的優化
在上一節中咱們提到是,ART的機制使得apk在安裝的時候比較耗時,爲了改變這種狀態,在Android N(Android7.0)中對此作了優化。Android N實現了一個使用AOT、解釋、JIT混合模式的運行環境,這裏使用的JIT是改進後的JIT,ART也提供了一種新的、更快的解釋器。這種方式在apk安裝的過程當中再也不進行預編譯,第一次運行該應用相關程序後,在手機處於idle狀態和充電的時候再將運行過的程序編譯爲機器碼並存儲在設備中。JIT提供了一套追蹤機制來決定哪一部分代碼須要在手機idle和充電的時候來編譯(即熱區域hot method的肯定),這個追蹤技術被稱爲Profile Guided Compilation,其工做原理以下:
(1)應用程序第一次啓動的時候,只會經過解釋器執行,同時JIT會介入並針對hot methods執行優化工做。代碼在執行期間會被分析,分析結果被保存起來,同步輸出一種被稱爲profile information的信息保存到文件中。該文件中記錄了須要離線優化的hot methods,影響程序啓動速度的Classes,它們主要用於進一步優化程序的啓動速度。
(2)當設備處於idle狀態而且在充電,就會進入Profile Guided Compilation服務,使用第一步中的profile information,生成二進制機器碼,用於替代原始應用程序的相應部分。
(3)應用程序在後續啓動時,就能夠根據實際狀況在AOT/JIT/Interpreter中選擇最合適的執行方式了。
經過以上的步驟能夠得知,由於有了Profile Guided Compilation,同一app會由於不一樣的用戶行爲產生不一樣的編譯結果。
咱們能夠歸納性地作一個總結:第一次運行到某些模塊的程序的時候(這次JIT信息不會持久化),產生一個文件來記錄這些被執行的程序信息,從而實現了將以往在安裝過程當中預編譯生成機器碼的過程,延遲到手機處於idle和充電的時候來完成,最終實現既能避免漫長的安裝等待,又不影響程序啓動速度,還節約了空間(由於有些功能程序一直不被使用,就不須要編譯爲機器碼佔用空間),cpu資源,電池資源等的目的。
參考資料