Android面试收集录13 Android虚拟机及编译过程
?
一、什么是Dalvik虛擬機
Dalvik是Google公司自己設計用于Android平臺的Java虛擬機,它是Android平臺的重要組成部分,支持dex格式(Dalvik Executable)的Java應用程序的運行。dex格式是專門為Dalvik設計的一種壓縮格式,適合內(nèi)存和處理器速度有限的系統(tǒng)。Google對其進行了特定的優(yōu)化,使得Dalvik具有高效、簡潔、節(jié)省資源的特點。從Android系統(tǒng)架構(gòu)圖知,Dalvik虛擬機運行在Android的運行時庫層。
Dalvik作為面向Linux、為嵌入式操作系統(tǒng)設計的虛擬機,主要負責完成對象生命周期管理、堆棧管理、線程管理、安全和異常管理,以及垃圾回收等。另外,Dalvik早期并沒有JIT編譯器,直到Android2.2才加入了對JIT的技術(shù)支持。
?
?
二、Dalvik虛擬機的特點
體積小,占用內(nèi)存空間小;
專有的DEX可執(zhí)行文件格式,體積更小,執(zhí)行速度更快;
常量池采用32位索引值,尋址類方法名,字段名,常量更快;
基于寄存器架構(gòu),并擁有一套完整的指令系統(tǒng);
提供了對象生命周期管理,堆棧管理,線程管理,安全和異常管理以及垃圾回收等重要功能;
所有的Android程序都運行在Android系統(tǒng)進程里,每個進程對應著一個Dalvik虛擬機實例。
?
?
三、Dalvik虛擬機和Java虛擬機的區(qū)別
Dalvik虛擬機與傳統(tǒng)的Java虛擬機有著許多不同點,兩者并不兼容,它們顯著的不同點主要表現(xiàn)在以下幾個方面:
Java虛擬機運行的是Java字節(jié)碼,Dalvik虛擬機運行的是Dalvik字節(jié)碼。
傳統(tǒng)的Java程序經(jīng)過編譯,生成Java字節(jié)碼保存在class文件中,Java虛擬機通過解碼class文件中的內(nèi)容來運行程序。而Dalvik虛擬機運行的是Dalvik字節(jié)碼,所有的Dalvik字節(jié)碼由Java字節(jié)碼轉(zhuǎn)換而來,并被打包到一個DEX(Dalvik Executable)可執(zhí)行文件中。Dalvik虛擬機通過解釋DEX文件來執(zhí)行這些字節(jié)碼。
Dalvik可執(zhí)行文件體積小。Android SDK中有一個叫dx的工具負責將Java字節(jié)碼轉(zhuǎn)換為Dalvik字節(jié)碼。
dx工具對Java類文件重新排列,消除在類文件中出現(xiàn)的所有冗余信息,避免虛擬機在初始化時出現(xiàn)反復的文件加載與解析過程。一般情況下,Java類文件中包含多個不同的方法簽名,如果其他的類文件引用該類文件中的方法,方法簽名也會被復制到其類文件中,也就是說,多個不同的類會同時包含相同的方法簽名,同樣地,大量的字符串常量在多個類文件中也被重復使用。這些冗余信息會直接增加文件的體積,同時也會嚴重影響虛擬機解析文件的效率。消除其中的冗余信息,重新組合形成一個常量池,所有的類文件共享同一個常量池。由于dx工具對常量池的壓縮,使得相同的字符串,常量在DEX文件中只出現(xiàn)一次,從而減小了文件的體積。
針對每個Class文件,都由如下格式進行組成:
dex格式文件使用共享的、特定類型的常量池機制來節(jié)省內(nèi)存。常量池存儲類中的所有字面常量,它包括字符串常量、字段常量等值。
簡單來講,dex格式文件就是將多個class文件中公有的部分統(tǒng)一存放,去除冗余信息。
**Java虛擬機與Dalvik虛擬機架構(gòu)不同。**這也是Dalvik與JVM之間最大的區(qū)別。
Java虛擬機基于棧架構(gòu),程序在運行時虛擬機需要頻繁的從棧上讀取或?qū)懭霐?shù)據(jù),這個過程需要更多的指令分派與內(nèi)存訪問次數(shù),會耗費不少CPU時間,對于像手機設備資源有限的設備來說,這是相當大的一筆開銷。Dalvik虛擬機基于寄存器架構(gòu)。數(shù)據(jù)的訪問通過寄存器間直接傳遞,這樣的訪問方式比基于棧方式要快很多。
?
四、Dalvik虛擬機的結(jié)構(gòu)
一個應用首先經(jīng)過DX工具將class文件轉(zhuǎn)換成Dalvik虛擬機可以執(zhí)行的dex文件,然后由類加載器加載原生類和Java類,接著由解釋器根據(jù)指令集對Dalvik字節(jié)碼進行解釋、執(zhí)行。最后,根據(jù)dvm_arch參數(shù)選擇編譯的目標機體系結(jié)構(gòu)。
?
五、Android APK 編譯打包流程
1.Java編譯器對工程本身的java代碼進行編譯,這些java代碼有三個來源:app的源代碼,由資源文件生成的R文件(aapt工具),以及有aidl文件生成的java接口文件(aidl工具)。產(chǎn)出為.class文件。
①.用AAPT編譯R.java文件
②編譯AIDL的java文件
③把java文件編譯成class文件
2..class文件和依賴的三方庫文件通過dex工具生成Delvik虛擬機可執(zhí)行的.dex文件,包含了所有的class信息,包括項目自身的class和依賴的class。產(chǎn)出為.dex文件。
3.apkbuilder工具將.dex文件和編譯后的資源文件生成未經(jīng)簽名對齊的apk文件。這里編譯后的資源文件包括兩部分,一是由aapt編譯產(chǎn)生的編譯后的資源文件,二是依賴的三方庫里的資源文件。產(chǎn)出為未經(jīng)簽名的.apk文件。
4.分別由Jarsigner和zipalign對apk文件進行簽名和對齊,生成最終的apk文件。
總結(jié)為:編譯-->DEX-->打包-->簽名和對齊
?
六、ART虛擬機與Dalvik虛擬機的區(qū)別
什么是ART:
ART代表Android Runtime,其處理應用程序執(zhí)行的方式完全不同于Dalvik,Dalvik是依靠一個Just-In-Time (JIT)編譯器去解釋字節(jié)碼。開發(fā)者編譯后的應用代碼需要通過一個解釋器在用戶的設備上運行,這一機制并不高效,但讓應用能更容易在不同硬件和架構(gòu)上運 行。ART則完全改變了這套做法,在應用安裝時就預編譯字節(jié)碼到機器語言,這一機制叫Ahead-Of-Time (AOT)編譯。在移除解釋代碼這一過程后,應用程序執(zhí)行將更有效率,啟動更快。
ART優(yōu)點:
ART缺點:
ART虛擬機相對于Dalvik虛擬機的提升
預編譯
在dalvik中,如同其他大多數(shù)JVM一樣,都采用的是JIT來做及時翻譯(動態(tài)翻譯),將dex或odex中并排的dalvik code(或者叫smali指令集)運行態(tài)翻譯成native code去執(zhí)行.JIT的引入使得dalvik提升了3~6倍的性能。
而在ART中,完全拋棄了dalvik的JIT,使用了AOT直接在安裝時將其完全翻譯成native code.這一技術(shù)的引入,使得虛擬機執(zhí)行指令的速度又一重大提升
垃圾回收機制
首先介紹下dalvik的GC的過程.主要有有四個過程:
dalvik這么做的好處是,當pause了之后,GC勢必是相當快速的.但是如果出現(xiàn)GC頻繁并且內(nèi)存吃緊勢必會導致UI卡頓,掉幀.操作不流暢等。
后來ART改善了這種GC方式 ,?主要的改善點在將其非并發(fā)過程改變成了部分并發(fā).還有就是對內(nèi)存的重新分配管理。
當ART GC發(fā)生時:
可以看出整個過程做到了部分并發(fā)使得時間縮短.據(jù)官方測試數(shù)據(jù)說gc效率提高2倍
提高內(nèi)存使用,減少碎片化
Dalvik內(nèi)存管理特點是:內(nèi)存碎片化嚴重,當然這也是Mark and Sweep算法帶來的弊端
可以看出每次gc后內(nèi)存千瘡百孔,本來連續(xù)分配的內(nèi)存塊變得碎片化嚴重,之后再分配進入的對象再進行內(nèi)存尋址變得困難。
ART的解決:在ART中,它將Java分了一塊空間命名為Large-Object-Space,這塊內(nèi)存空間的引入用來專門存放large object。同時ART又引入了moving collector的技術(shù),即將不連續(xù)的物理內(nèi)存塊進行對齊.對齊了后內(nèi)存碎片化就得到了很好的解決.Large-Object-Space的引入一是因為moving collector對大塊內(nèi)存的位移時間成本太高,而且提高內(nèi)存的利用率 根官方統(tǒng)計,ART的內(nèi)存利用率提高10倍了左右。
?
七、參考文章
https://github.com/LRH1993/android_interview/blob/master/android/basis/dalvik-art.md
?
轉(zhuǎn)載于:https://www.cnblogs.com/Jason-Jan/p/8459105.html
總結(jié)
以上是生活随笔為你收集整理的Android面试收集录13 Android虚拟机及编译过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (自兴人工智能)python字符串
- 下一篇: ps 命令详解