㈠ 強制dex2oat傷手機嗎
傷手機。dex2oat是在安裝app的時候轉化java代碼到機器碼,這樣會大幅提高程序效率,根據查詢相關資料顯示,如果強制停止dex2oat會導致手機卡頓,因為違背了art虛擬機設計的初衷會影響運行速度,久而久之會傷害手機運行速度,不能夠強制停止dex2oat的運行。
㈡ 安卓art和dalvik的區別
Dalvik是Google公司自己設計用於android平台的Java虛擬機。Dalvik虛擬機是Google等廠商合作開發的Android移動設備平台的核心組成部分之一。它可以支持已轉換為 .dex(即Dalvik Executable)格式的Java應用程序的運行,.dex格式是專為Dalvik設計的一種壓縮格式,適合內存和處理器速度有限的系統。Dalvik 經過優化,允許在有限的內存中同時運行多個虛擬機的實例,並且每一個Dalvik 應用作為一個獨立的linux 進程執行。獨立的進程可以防止在虛擬機崩潰的時候所有程序都被關閉。
Android操作系統已經成熟,Google的Android團隊開始將注意力轉向一些底層組件,其中之一是負責應用程序運行的Dalvik運行時。Google開發者已經花了兩年時間開發更快執行效率更高更省電的替代ART運行時。 ART代表Android Runtime,其處理應用程序執行的方式完全不同於Dalvik,Dalvik是依靠一個Just-In-Time (JIT)編譯器去解釋位元組碼。開發者編譯後的應用代碼需要通過一個解釋器在用戶的設備上運行,這一機制並不高效,但讓應用能更容易在不同硬體和架構上運 行。ART則完全改變了這套做法,在應用安裝時就預編譯位元組碼到機器語言,這一機制叫Ahead-Of-Time (AOT)編譯。在移除解釋代碼這一過程後,應用程序執行將更有效率,啟動更快。
㈢ 如何在刷機包里開啟dex2oat模式
刷機准備工作:1、保證手機有充足的電量(70%以上);2、備份手機中的個人數據(聯系人、簡訊、應用程序等);3、下載官方包或其它刷機包(可以到官網論壇,ROM基地下載)。方法步驟:1、首先將刷機包包拷貝到手機存儲卡的根目錄下。2、關機狀態下,同時按住電源鍵與音量下鍵,約十秒鍾時間之後,屏幕上將出現黑底黃字,這說明手機已經進入Recovery模式。3、使用音量上、下按鍵將游標移動到「手動選擇安裝包」位置,點擊電源鍵進行確認。接下來使用音量上、下按鍵選擇安裝包,點擊電源鍵進行確認。 4、只需等待自行完成,機過程中手機始終保持屏幕點亮狀態,除了不斷滾動的黃色文字之外還有藍色的進度條顯示在綠色機器人的下方。最終屏幕最下方將顯示「安裝完成」字樣,機完成,5、根據提示選擇立即重啟系統,完成。
㈣ 強制dex2oat傷手機嗎
強制dex2oat傷手機,因為dex2oat佔用cpu資源太多,導致cpu資源緊張,系統卡頓。dex2oat是一個對dex文件進行編譯優化的程序,在我們的Android手機中的位置是/system/bin/dex2oat,對應的源碼路徑為android/art/dex2oat/dex2oat.cc,通過編譯優化,可以提升用戶日常的使用體驗(包含安裝速度、啟動速度、應用使用過程中的流暢度等),是AndroidArtRuntime中的一個重要的模塊。
㈤ 細說dex2oat(1) - dex2oat的命令行參數
首先我們先看一下dex2oat都支持一些什麼樣的命令行參數:
上面我們學習了dex2oat的參數的簡介,下面我們學以致用,看看在真實的環境中它們是如何被使用的。
我們直接看build時,dex2oat的參數是如何被傳進去的,在build/core/dex_preopt_libart.mk中:
首先指定兩個運行時參數,這兩個參數是在前面定義的:
也就是說,這兩個值取自屬性dalvik.vm.dex2oat-Xms和vm.dex2oat-Xmx。這兩個屬性是哪裡來的呢,是在/build/target/proct/runtime_libart.mk中,編譯的時候指定進來的:
這樣,這兩個值分別是64m和512m。
我們回到dex_preopt_libart.mk中繼續看:
查這個PRIVATE_DEX_PREOPT_IMAGE_LOCATION,定義於/build/core/setup_one_odex.mk中:
然後再向上追my_dex_preopt_image_location
LOCAL_DEX_PREOPT_IMAGE_LOCATION沒有定義,繼續順藤摸瓜。
再繼續追DEXPREOPT_BOOT_JAR_DIR_FULL_PATH:
先看後面的DEXPREOPT_BOOT_JAR_DIR,原來就是system/framework
再看前面的DEXPREOPT_PRODUCT_DIR_FULL_PATH,是out下的dex_bootjars
最後 --boot-image 的值為 out/dex_bootjars/system/framework/boot.art
這個就不多說了
追查:
這個板級驅動已經配好了。
在同樣的位置定義:
include-patch-information兼runtime-arg -Xnorelocate,生成重定位的信息,因為後面還要走patchoat呢。
no-generate-debug-info,不生成調試信息
大家留神啊,現在已經是selinux的時代了,dex2oat也需要配置相關的許可權:
這還不算,在installd的許可權配置/external/sepolicy/installd.te中,明確設置了
前面講的參數中,有一項是--boot-image。我們先看一下這個boot-image是如何編出來的,正好是一個完整的dex2oat的例子.
我們看下在MediaTek MT6753平台下,是如何生成的。
MT6753是64位Cortex-A53的架構,所以boot.art也是64位和32位兩套。
先看64位的吧:
初始堆大小和最大堆大小。
預載入類的路徑
以上是一大堆的dex文件
以上是上面那一大堆dex對應的jar文件路徑
符號表的位置
輸出文件有兩個:一個是boot.oat,一個是boot.art。
基地址0x70000000
對於指令架構,除了arm64,更細的是cortex-a53
最後這幾個前面都說過了。
上面都是java和dex,所以跟64位沒有什麼區別。
輸出文件從arm64目錄換到了arm目錄
基地址沒變,反正patchoat的時候也還要改。
指令集從arm64變成了arm,其它的參數都不變
這兩個值在前面分析Android.oat.mak時已經分析過了,這里驗證了我們的分析是正確的。
這個boot.art就是上一節講的命令剛剛生成的。
輸入的dex文件
輸出到odex文件,雖然名字叫odex,但是實際上是個oat。普通的應用就不像上節講的輸出boot.oat和boot.art的時候那樣輸出那麼多了,只有一個odex文件,符號表和image都不用。
在Android的mk系統中,調用dex2oat中有幾處,但是真正被調用來生成目標系統上的oat的是下面這個,位於/build/core/dex_preopt_libart.mk中:
這個dex2oat-one-file,是被dexpreopt-one-file調用,位於/build/core/dex_preopt.mk中:
以下根據生成的類型不同,包、庫、預先編譯好的應用有不同的路徑。
/build/core/package_internal.mk
/build/core/java_library.mk
我們再來看看,odex是如何被install到system分區下面的。
我們看一個實際的例子:
除了編譯之外,我們得先看一些預先定義好的函數。它們定義於/build/core/definitions.mk中。
將class文件壓縮成classes*.dex
將依賴文件復制到目標文件
㈥ dex2oat 有什麼用
dex2oat的用處:
眾所周知,Android虛擬機可以識別的是dex文件,應用使用過程中如果每次將dex文件載入進行內存,解釋性執行位元組碼,效率會很低,嚴重影響用戶體驗。
通過dex2oat優化後,可以在系統運行之前利用合適的時機將dex文件位元組碼提前轉化為虛擬機可以執行運行的機器碼。
後續直接從效率更高的機器碼中運行,則運行階段更加流暢,優化用戶體驗。
Dex2oat (dalvik excutable file to optimized art file),是一個對 dex 文件進行編譯優化的程序,在我們的 Android 手機中的位置是/system/bin/dex2oat。
對應的源碼路徑為 android/art/dex2oat/dex2oat.cc。
通過編譯優化,可以提升用戶日常的使用體驗(包含安裝速度、啟動速度、應用使用過程中的流暢度等),是 Android Art Runtime 中的一個重要的模塊, 本文我們一起來了解下 dex2oat 的功能以及常用的場景。
㈦ 安卓art虛擬機在什麼位置
一、概述
我們知道Android的程序雖然也是使用Java/Kotlin語言編碼,並生成.class位元組碼,但並不能直接運行在JVM上,而是運行在自己的VM上。而Android程序之所以不能在JVM上運行的根本原因是.class位元組碼文件並不是Android的最終可執行文件(執行效率問題),而是一個過渡產物,最終會生成dex文件在Android VM上執行。
1.1 Android虛擬機分類:
Android VM大體分為兩種: Dalvik 虛擬機和 ART虛擬機。
Dilvik 虛擬機:Android 5.0 版本之前。
ART虛擬機:Android 5.0 版本全面使用。
1.2 虛擬機的演變及優化:
Android 1.0,使用Dalvik作為Android虛擬機運行環境,此時的虛擬機是一個解釋執行器。
Android 2.2,Android 虛擬機中加入了JIT編譯器(Just-In-Time Compiler)。
Android 4.4,全新的ART虛擬機運行環境誕生,此時ART和Dalvik是共存的,用戶可以在兩者之間進行選擇。
Android 5.0,ART全面取代了Dalvik成為了Android虛擬機運行環境,並使用AOT預編譯技術在安裝Apk時全量預編譯 。
Android 7.0,ART虛擬機採用 JIT/AOT混合編譯模式。
二、Dalvik
Dalvik是Google公司自己設計用於Android平台的虛擬機,它是Android平台的重要組成部分,支持dex格式(Dalvik Executable)的Java應用程序的運行。dex格式是專門為Dalvik設計的一種壓縮格式,適合內存和處理器速度有限的系統。Google對其進行了特定的優化,經過優化的Dalvik,具有高效、簡潔、節省資源的特點,同時還允許在有限的內存中同時運行多個虛擬機的實例,並且每一個Dalvik 應用作為一個獨立的Linux進程執行。獨立的進程可以防止在虛擬機崩潰的時候所有程序都被關閉。
2.1 Dalvik和JVM的區別
Dalvik 基於寄存器,而 JVM 基於棧。
指令數量:基於寄存器的操作指令,會增加操作數的大小(劣勢),但是會大大減少操作指令的數量(優勢)
操作效率:基於寄存器(CPU上)的指令操作速度比基於操作數棧(主存)的速度快。
移植性:基於寄存器執行效率好,但是可移植性差,難跨平台。
Dalvik虛擬機有共享機制,不同應用之間在運行時可以共享相同的類,擁有更高的效率。
2.2 JIT(Just-In-Time Compile)
Android 2.2之前,Dalvik虛擬機是通過解釋器 (解釋器逐條讀入位元組碼 -> 逐條翻譯成機器碼 -> 執行機器碼)來執行程序的,效率低。針對這個問題,引進了JIT(即時編譯器)技術。它是一種優化手段。
JIT技術:將解釋過的機器碼緩存起來,下次再執行時到這個方法的時候,則直接從緩存裡面取出機器碼來執行。減少了讀取位元組碼和翻譯位元組碼的操作。以此來提高效率。JIT技術的引入使得Dalvik的性能提升了3~6倍。
注意: 並不是所有執行過的代碼對應的機器碼都會被緩存起來。而是只有被認定為熱點代碼(Hot Spot Code) 的代碼才會。這里所指的熱點代碼主要有兩類,包括:
被多次調用的方法
被多次執行的循環體(雖然只是循環體被多次執行,但仍是將整個方法的機器碼緩存起來)。
缺點: JIT技術的缺點:
每次重新啟動引用都需要重新編譯。
運行時比較耗電。
三、ART 虛擬機
ART虛擬機在Android 5.0開始替換Dalvik虛擬機,其處理應用程序執行的方式不同於Dalvik虛擬機,它不使用JIT而是使用了AOT(Ahead-Of-Time),也就是提前編譯技術。並對垃圾收集器也進行了改進和優化。
預先編譯機制(AOT)可提高應用的性能。同時ART 還具有比 Dalvik 更嚴格的安裝時驗證。
3.1 AOT(Ahead-Of-Time)預先編譯技術
AOT(提前編譯技術): 簡單來說就是提前將位元組碼轉換成本地機器碼,然後存儲在本地磁碟上,運行時可以直接執行,避免了Dalvik時期的應用運行時再來解釋位元組碼。運行時效率大大提高。
在Android 7.0 之前,Android系統安裝Apk時,會進行一次全量預編譯,將位元組碼預先編譯成本地機器碼,生成 oat文件,並存儲在本地磁碟上。這樣在App每次運行時就不需要重新編譯,可以直接使用編譯好本地機器碼,運行效率大大提升。但是這也使得安裝應用的時間大大增加,於是在Android7.0及之後,又重新引進了JIT技術,形成JIT/AOT混合編譯模式。
混合編譯的特點:
應用在安裝的時候,不進行AOT預編譯。
應用運行時直接通過解釋器翻譯位元組碼為機器碼然後執行。(在應用運行期間使用了JIT技術)並同時記錄熱點代碼信息到profile文件中。
手機進入空閑或充電狀態的時候,系統會掃描APP目錄下的profile文件,並通過AOT對熱點代碼進行編譯。
下一次啟動時,會根據profile文件來運行已編譯好的機器碼,避免在運行時對已經轉換為機器碼的方法又進行了JIT編譯。
應用運行期間會持續對熱點代碼進行記錄,以方便在空閑或充電時進行AOT,以此循環。
使用JIT編譯器來對AOT編譯器進行補充,降低了Apk安裝的時間,提升了運行時性能,節省了存儲空間,加快應用運行速度。
小結:
Android 7.0以前,採用AOT全量預編譯,Apk安裝時預編譯dex生成對應的機器碼文件。但預編譯量大導致Apk安裝時間長。
Android 7.0及之後,採用JIT/AOT混合編譯模式,根據對應的profile在空閑時進行AOT預編譯。
參考: 實現 ART 即時 (JIT) 編譯器
3.2 Dalvik與ART虛擬機的區別
Dalvik每次都要編譯再運行,Art只會安裝時啟動編譯(7.0之前全量預編譯)。
Art佔用空間比Dalvik大(原生代碼佔用的存儲空間更大),就是用「空間換時間」。
Art減少編譯,減少了CPU使用頻率,使用明顯改善電池續航。
Art應用啟動更快、運行更快、體驗更流暢、觸感反饋更及時。
3.3 Interpreter解釋器、JIT、AOT的在ART上的使用
解釋器: 逐條讀入位元組碼 -> 逐條翻譯成機器碼 -> 執行機器碼,重復執行同一代碼時需要重新翻譯執行。
JIT編譯器: 對運行時的熱點代碼(熱點代碼)進行編譯,且緩存在內存中,當下次繼續執行時,直接從內存中獲取,減少重復編譯。
AOT編譯器: 在運行前將位元組碼轉換為機器碼,在運行時直接運行轉換後的機器碼。
在這里插入圖片描述
3.4 垃圾回收方面的優化
Android虛擬機(Dalvik && ART)學習
四、Android中的幾種文件
4.1 Apk文件
APK 文件其實是 zip 格式,在Window平台上可以直接將後綴格式改為zip進行解壓。解壓後的目錄如下圖所示:
在這里插入圖片描述
文件名 說明
META-INF/ 信息描述,簽名等用途。編譯生成一個apk包時,會對所有要打包的文件做一個校驗計算,並把計算結果放在META-INF目錄下。而在Android手機上安裝apk包時,應用管理器會按照同樣的演算法對包里的文件做校驗,如果校驗結果與META-INF下的內容不一致,系統就不會安裝這個apk。這就保證了apk包里的文件不能被隨意替換
res/ 存放資源文件
libs/ 存放的是 ndk 編出來的 so 庫
AndroidManifest.xml 程序全局清單文件
classes.dex dalvik 位元組碼
resources.ars 編譯後的二進制資源文件,主要是對應的索引
assets/ 保留工程中assets目錄,其他工程下的、jar包中的assets也會合並到該assets目錄下。
4.2 dex文件
dex 文件是可被Dalvik虛擬機識別並執行的文件, Dalvik 會執行 .dex 文件中的 dalvik 位元組碼,但一般Dalvik在執行dex優化後的文件(即odex文件)。
dex文件特點:
dex文件是Android系統中的一種文件,是一種特殊的數據格式,和Apk、jar等格式文件類似。
文件更加緊湊:dex文件是能夠被DVM識別,載入並執行的文件格式。相比於Jar文件,dex會把所有包含的信息整合在一起,減少冗餘信息,從而降低了載入文件時的I/O耗時,提高類的查找速度。
dex文件包含應用程序的全部操作指令和運行時數據。
相對於PC上的JVM能運行 .class文件,Android上的Dalvik虛擬機能運行 .dex 文件。
.dex文件和 .class文件的格式對照:
在這里插入圖片描述
dex 文件結構:
在這里插入圖片描述
4.3 引起dex文件65535問題的原因
當Android系統啟動一個Apk時,會通過 dexopt 工具對dex進行優化。dexopt 的執行過程是在第一次載入dex文件的時候執行的。這個過程會生成一個odex文件,即Optimised Dex (執行odex的效率會比直接執行Dex文件的效率要高很多)。但早期Android系統中, dexopt 有一個問題(即65535問題)。dexopt會把每一個類的方法id檢索起來,存在一個鏈表結構裡面。但是這個鏈表的長度是用一個 short類型(2^16=65536)來保存的,導致了方法id的數目不能夠超過65536個。
4.4 odex文件 (Optimized DEX)
背景: 對Android dex文件進行優化來說,需要注意的一點是dex文件的結構是緊湊的,但是我們還是要想方設法進行運行速度的提高,因此我們仍然需要對dex文件進一步優化。
odex文件的使用場景:
安裝階段: Apk在安裝時,系統會進行驗證和優化,目的是為了校驗代碼合法性及優化代碼執行速度。當驗證和優化後,系統會從Apk中提取dex文件進行優化,並將優化後的產物(odex文件)保存到 data/dalvik-cache 目錄下。
運行階段: 當運行Apk的時候,會直接載入odex文件,避免重復驗證和優化,加快了Apk的響應時間。
odex 文件的生成過程:
Android 5.0之前:Dalvik虛擬機
Dalvik虛擬機會在執行dex文件前對dex文件做優化,生成可執行文件odex,保存到 data/dalvik-cache 目錄,最後把Apk文件中的dex文件刪除。
注意: 此時生成的odex文件後綴依然是dex ,它是一個dex文件,裡面仍然是位元組碼,而不是本地機器碼。
Android5.0 <= Version < Android 8.0 (Android O):ART虛擬機
Android5.0之後使用ART虛擬機,ART虛擬機使用AOT預編譯生成oat文件。oat文件是ART虛擬機運行的文件,是ELF格式二進制文件。oat文件包含dex和編譯的本地機器指令,因此比Android5.0之前的odex文件更大。
oat文件生成過程:
App在首次安裝的時候,dex2oat 工具默認會把 dex文件翻譯成本地機器指令,生成ELF格式的OAT文件,並將其放在了 /data/dalvik-cache 或 /data/app/packagename/ 目錄下,此時oat文件後綴格式為odex。
ART載入oat文件後不需要經過處理就可以直接運行,它在編譯時就從位元組碼裝換成機器碼了,因此運行速度更快。
Dalvik虛擬機執行程序dex文件前,系統會對dex文件做優化,生成可執行文件odex,保存到 data/dalvik-cache 目錄,最後把apk文件中的dex文件刪除。 (注意:此時生成的odex文件後綴依然是dex ,它是一個dex文件,裡面仍然還是位元組碼,而不是本地機器碼。)
注意: Android5.0及之後版本生成的 oat文件後綴還是odex,但是已經不是android5.0 及之前版本的文件格式,而是ELF格式封裝的本地機器碼。可以認為oat在dex上加了一層殼,可以從oat里提取出dex。
Android O及之後(>=Android 8.0):ART虛擬機
Android 8.0及之後版本,dex2oat會直接生成兩個oat文件 (即vdex文件 和 odex文件)。其中 odex 文件是從vdex 文件中提取了部分模塊生成的一個新的可執行二進制碼文件,odex 從vdex 中提取後,vdex 的大小就減少了。
文件生成過程:
App在首次安裝的時候,odex 文件就會生成在 /system/app/<packagename>/oat/ 下。
在系統運行過程中,虛擬機將其 從/system/app 下 到 /data/davilk-cache/ 下。
odex + vdex = Apk 的全部源碼 (vdex 並不是獨立於odex 的,文件 odex + vdex 才代表一個Apk )。
odex 的優點和缺點:
優點:
啟動快: 省去了系統第一次啟動應用時從Apk文件中讀取dex文件,並對dex文件做優化的過程。和
對RAM的佔用(Apk文件中的dex如果不刪除,同一個應用就會存在兩個dex文件:apk中和 data/dalvik-cache 目錄下)。
安全性:防止第三方用戶反編譯系統的軟體(odex文件是跟隨系統環境變化的,改變環境會無法運行;而apk文件中又不包含dex文件,無法獨立運行)
劣勢:
優化後的odex文件大小通常是原dex文件的1~4倍 (空間換時間)。
4.5 vdex文件
vdex文件是 Android O (Android 8.0) 新增的格式包,其目的是為了降低dex2oat時間。
dex2oat的觸發場景:
當系統OTA (系統升級) 後,用戶自己安裝的應用是不會發生任何變化的,但 framework 代碼已經發生了變化,因此就需要重新對這些應用也做dex2oat。如果沒有vdex文件,則需要重新校驗Apk里dex文件合法性;如果存在vdex文件,就可以省略校驗的過程,節省一部分時間。
當App的 JIT Profile 信息變化時,background dexopt會在後台重新做dex2oat,因為有了vdex,這個時候也可以直接跳過dex文件的校驗流程。
dex 文件直接轉化的可執行二進制碼文件:
App在首次安裝的時候,vdex文件就會生成在 /system/app/<packagename>/oat/下。
在系統運行過程中,虛擬機將其從 /system/app 下 到 /data/davilk-cache/ 下。
4.6 art文件
art文件是由虛擬機執行odex文件後,記錄虛擬機執行Apk啟動的常用函數地址信息後生成出來的文件(記錄函數地址信息方便定址),目的 是用於加快應用啟動速度。通常會在data/dalvik-cache/ 目錄中保存常用的jar包的相關地址記錄。
第一次開機不會生成在 /system/app/<packagename>/oat/ 下,以後也不會。
odex 文件在運行時,虛擬機會計算函數調用頻率,進行函數地址的修改。
最後在 /data/davilk-cache/ 由虛擬機生成 art文件(art文件生成)。
生成 art文件後,/system/app 下的odex 和 vdex 會無效,即使你刪除,apk也會正常運行。
push 一個新的apk file 覆蓋之前 /system/app 下Apk file ,會觸發 PMS 掃描時下發 force_dex 的flag ,強行生成新的vdex 文件 ,覆蓋之前的vdex 文件,由於某種機制,這個新vdex 文件會到 /data/dalvik-cache/ 下,於是 art 文件也變化了。
4.7 oat文件
ART虛擬機運行的是oat文件,oat文件是一種Android私有ELF文件格式,oat文件包含有從dex文件翻譯而來的本地機器指令,還包含有原來的dex文件內容(如下圖所示),因此oat文件比odex文件更大。APK在安裝的過程中,會通過dex2oat工具生成一個OAT文件(文件後綴還是odex)。對於apk來說,oat文件實際上就是對odex文件的包裝,即oat=odex。
注意: Android5.0 及之後的版本,oat文件的後綴還是odex,但是已經不是android5.0 之前的文件格式,而是ELF格式封裝的本地機器碼。可以認為oat在dex上加了一層殼,可以從oat里提取出dex。