一、Android系統性能提升之路
Dalvik虛擬機作為Android平臺的核心組成部分之一,允許在有限的內存資源中同時運行多個虛擬機實例。Dalvik虛擬機通過以下方式提升性能:
1、DEX代碼安裝時或第一次動態加載時odex化處理。
2、Android2.2版本提供瞭JIT機制提升性能,號稱性能提升3~5倍。
3、提升硬件配置,如更多核CPU、更高頻率CPU、更大的RAM等。
但是Android的系統流暢度與IOS系統還是有一定得差距。Android代碼必須運行在Dalvik虛擬機上,而IOS直接是本地代碼,性能差距也在情理之中。如果Android系統想擁有與IOS系統相同的系統性能。Dalvik虛擬機運行機制就成為Android系統性能提升唯一的障礙。
Android Kitkat 提供瞭一種與Dalvik截然不同的運行環境-ART(Android Runtime)的支持。目前用戶可以選擇設備的運行環境,在不久的將來ART肯定會替代Dalvik Runtime。
二、Dalvik vs ART
Dalvik運行環境使用JIT(Just-In-Time)來進行轉譯,應用每次運行的時候,字節碼都需要通過JIT轉換為機器碼,這會拖慢應用的運行效率。而ART則是使用AOT進行處理(Ahead-Of-Time),並會在應用程序安裝完畢時,進行預先的基礎性編譯作業,這就減去瞭JIT運行時的機器碼轉化時間,應用的啟動和執行都會變得更加快速。
ART優點:
1、系統性能的顯著提升。
2、應用啟動更快、運行更快、體驗更流暢、觸感反饋更及時。
3、更長的電池續航能力。
4、支持更低的硬件。
ART缺點:
1、更大的存儲空間占用,可能會增加10%-20%。
2、更長的應用安裝時間。
總的來說ART的功效就是“空間換時間”。
三、初步感知ART
1、設備如何選擇ART運行環境
通過以下步驟開啟:設置→關於手機→點擊最下面的版本號7次→開發者模式出現→返回→進入開發者模式,然後選擇runtime-使用ART
目前官方Android模擬器並不能開啟ART模式,可以通過該網址下載支持ART模式的Android模擬器鏡像 ( https://blog.csdn.net/coolypf/article/details/17069015)
2、Dalvik切換ART後系統變化
2.1、應用安裝時采用的代碼優化方式不同:
Dalvik Runtime : dex2opt(https://124.16.139.131:24080/lxr/source/dalvik/dexopt/OptMain.cpp?v=android-4.0.4#f_OptMain.cpp)
ART Runtime : dex2oat (https://android.googlesource.com/platform/art/+/kitkat-release/dex2oat/dex2oat.cc)
2.2、優化後的文件大小及格式不同:
兩個運行環境產生的優化代碼路徑及文件名都為:/data/dalvik-cache/app/data@app@{package name}.apk@classes.dex
ART環境產生的優化代碼文件大小明顯比Dalvik環境產生大:
雖然都為.dex文件結尾,但是文件格式卻是天壤之別:
ART環境文件格式:ELF Shared Object
Dalvik環境文件格式:
三、ART相關源代碼
ART相關源代碼下載地址:(https://android.googlesource.com/platform/art/+archive/kitkat-release.tar.gz)
從源代碼文件目錄名稱可以很清楚的瞭解各文件夾中相關文件的功能,我們最關心的主要有compiler、dex2oat、runtime三個文件夾:
compiler:主要負責Dalvik字節碼到本地代碼的轉換,編譯為libart-compiler.so
dex2oat :完成DEX文件到ELF文件轉換。編譯為dex2oat
runtime :Android ART運行時源代碼,編譯為libart.so
四、dex2oat優化流程
在應用安裝時,installd通過dex2oat優化APK安裝包classes.dex的Dalvik字節碼為本地機器代碼。整個優化為:
更多LLVM編譯器的信息可查看:
https://llvm.org/
https://www.ibm.com/developerworks/cn/opensource/os-createcompilerllvm1/
https://www.chinaicexpo.com/market/1104-llvm.html
五、OAT文件格式
OAT文件其實就是基於ELF格式的一種私有文件格式。
OAT的ELF 段信息:
OAT的ELF export信息:
OAT文件加載流程,通過分析ART相關源碼,當通過DexClassLoader加載一個OAT文件基本流程如下:
1、讀取oatdata符號地址獲取Oat數據 startAddress。
2、讀取oatlastword符號地址獲取OAT數據 endAddress。
3、通過startAddress和endAddress定位Oat數據。
4、解析Oat數據。構建方法定位所需數據結構。
然後就可以調用加載OAT文件的代碼瞭。
整個的方法定位過程和Dalvik運行環境沒有太大區別,讀者可以通過(https://blog.csdn.net/androidsecurity/article/details/8664778)來瞭解如何定位到一個類的某個方法。
您可以簡單的認為ART和Dalvik區別就是:Dalvik定位到的方法是Davlik字節碼,但是ART定位到的方法是本地代碼。僅是方法代碼內容發生瞭變化,但是方法的定位過程基本相同。
我們以關鍵的地址點為分割截取OAT文件數據段:
ELF頭:
OAT數據內容開始:(註意0x10BB位置,DexHeader開始)
可執行本地代碼部分:
OAT數據結束位置:
具體的OAT文件格式可以查看源代碼。