網站首頁 編程語言 正文
前言
雖然Android程序是使用Java語言開發的,當然,現在也可以使用kotlin語言。但是實際上我們開發出來的Android程序并不能運行在JVM上,而是只能運行在一個類似JVM的Android虛擬機上。Android虛擬機有兩種,分別是Dalvik虛擬機和ART虛擬機。
Dalvik 虛擬機
Dalvik虛擬機是Google自己設計的用于Android平臺的虛擬機,它曾經是Android平臺的核心組成部分之一。它負責加載dex/odex文件并解析成機器碼然后執行。Dalvik虛擬機并沒有遵循《Java虛擬機規范》,因此不能算是Java虛擬機。但是它與Java卻又有聯系,它執行的DEX文件是通過Class文件轉化而來。我們也可以認為它是為了能在安卓設備運行而對JVM進行優化的產物。
Dalvik誕生消亡史
- Android 1.0,使用Dalvik作為Android虛擬機運行環境。
- Android 2.2,Google在Andriod虛擬機中加入了JIT編譯器(Just-In-Time Compiler)。
- Android 4.4,Google帶來了全新的虛擬機運行環境ART,此時ART和Dalvik是共存的,用戶可以在兩者之間進行選擇。
- Android 5.0,ART全面取代了Dalvik成為了Android虛擬機運行環境,至此Dalvik退出歷史舞臺。
Dalvik 特點 (與JVM的區別)
- Dalvik虛擬機運行的是Dalvik字節碼,Dalvik字節碼由Java字節碼轉換而來,并被打包到一個dex文件中。而JVM運行的是class文件或jar文件。
- 加載速度快,dex相比于Jar文件會把所有包含的信息整合在一起,減少了冗余信息。這樣就減少I/O操作,提高類的查找速度。
- Dalvik虛擬機是基于寄存器,而JVM是基于棧(操作數棧)。雖然基于寄存器執行效率好,但是可移植性差,難跨平臺。
- Dalvik虛擬機允許在有限的內存中同時運行多個進程,每一個應用都運行在一個Dalvik虛擬機實例中,擁有獨立的進程空間。
- Dalvik虛擬機有共享機制,不同應用之間在運行時可以共享相同的類,擁有更高的效率。
什么是JIT(Just-In-Time Compiler)
早期沒有JIT的時候,虛擬機運行時,會通過解釋器來解釋字節碼并將其翻譯為機器碼,逐條讀入,逐條翻譯,最后再執行,這樣就比較慢,效率不高。針對上面這個問題,引進了JIT(即時編譯器)技術。它是一種優化手段。
JIT技術簡單來說就是將解釋過的機器碼緩存起來,下次再執行時到這個方法的時候,則直接從緩存里面取出機器碼來執行。減少了讀取字節碼和翻譯字節碼的操作。以此來提高效率。JIT技術的引入使得Dalvik的性能提升了3~6倍
不過要注意的是并不是所有執行過的代碼對應的機器碼都會被緩存起來。而是只有被認定為熱點代碼(Hot Spot Code) 的代碼才會。這里所指的熱點代碼主要有兩類,包括:
- 被多次調用的方法
- 被多次執行的循環體(雖然只是循環體被多次執行,但仍是將整個方法的機器碼緩存起來)
JIT技術雖好,但是也是有缺點的:
- 每次重新啟動引用都需要重新編譯
- 運行時比較耗電
什么是dex
dex是二進制文件,用于在Android虛擬機上執行。是通過把所有的class文件進行合并優化得到的。dex文件去除了class文件中的冗余信息(比如重復字符串),并且結構更加緊湊,因此在dex解析階段可以減少I/O操作,提高類查找速度。
它與.jar文件不同,.jar文件像是一個文件夾,里面的.class是單獨的文件,各個class信息里面會出現重復的信息。而dex文件,則將所有的.class里面的信息整合在一起,去除掉里面的重復數據。
什么是odex
odex是從apk提取出dex文件并通過優化后得到的產物,它被保存到data/dalvik-cache目錄下。原apk文件中的classes.dex可以保留也可以刪除,甚至有時候會留下殘缺的dex文件。
系統在首次啟動時,需要對預置的apk進行安裝,此時需要將dex從apk文件中解壓出來放到data/app文件夾中。
- 在Dalvik虛擬機中,會通過dexopt來對dex進行優化,生成odex文件,并將其保存到手機的VM緩存文件夾data/dalvik-cache下(注意,這邊生成的odex文件后綴依然是dex )。它是一個dey文件,里面仍然還是字節碼。
- 在ART虛擬機上,同樣會在首次進入系統的時候使用dexopt工具來對dex進行優化,不過此時的優化是將dex字節碼翻譯成本地機器碼。并保存在data/dalvik-cache下。
一般情況下,在Android系統進行編譯的時候,預處理提取Odex文件的話,將會大大優化系統首次啟動時間。
ART 虛擬機
ART虛擬機在Android 5.0開始替換Dalvik虛擬機。其處理應用程序執行的方式不同于Dalvik虛擬機,它不使用JIT而是使用了AOT(Ahead-Of-Time),也就是提前編譯技術。并且對垃圾收集器也進行了改進和優化,當然也還包括了其他的優化。
什么是AOT(Ahead-Of-Time
AOT也就是提前編譯技術。簡單來說就是提前將字節碼轉換成本地機器碼,然后存儲在本地磁盤上,運行時可以直接執行,避免了Dalvik時期的應用運行時再來解釋字節碼。運行時效率大大提高。
在Android 7.0 之前,Android系統安裝應用的時候,會進行一次預編譯,將字節碼預先編譯成本地機器碼,生成.oat文件,并存儲在本地磁盤上,也就是AOT技術。這樣在應用每次運行時就不需要重新編譯,可以直接使用編譯好本地機器碼,運行效率大大提升。但是這也使得安裝應用的時間大大增加,
于是在Android7.0,又重新引進了JIT技術,形成JIT/AOT混合編譯模式,這種混合編譯的特點是:
- 應用在安裝的時候,不進行AOT預編譯。
- 應用運行時這直接通過解釋器翻譯字節碼為機器碼然后執行。并同時記錄熱點代碼信息到profile文件中。
- 手機進入空閑或充電狀態的時候,系統會掃描APP目錄下的profile文件,并通過AOT對熱點代碼進行編譯。
- 下一次啟動時,會根據profile文件來運行已編譯好的機器碼,避免在運行時對已經變過的方法又進行了JIT編譯。
- 應用運行期間會持續對熱點代碼進行記錄,以方便在空閑或充電時進行AOT,以此循環。
使用了JIT來對AOT進行補充,可以提升運行時性能,節省存儲空間,加快應用運行速度。 具體可以查看google官方文檔:實現 ART 即時 (JIT) 編譯器
ART垃圾收集器優化
- 只有一次GC暫停(Dalvik需要兩次)
- 并發復制,可減少后臺內存使用和碎片
- GC暫停的時間不受堆大小影響
- 在清理最近分配的短時對象這種特殊情況中,回收器的總GC時間更短
- 優化了垃圾回收的工效,能夠更加及時地進行并行垃圾回收,這使得GC_FOR_ALLOC事件在典型用例中極為罕見
ART時間線
- Android 4.4 ,ART和Dalvik是共存的,用戶可以在兩者之間進行選擇。
- Android 5.0,正式取代Dalvik虛擬機成為Android虛擬機運行環境,Dalvik退出歷史舞臺,AOT取代JIT。
- Android 7.0,JIT回歸,采用JIT和AOP混合編譯模式。
- ART持續更新優化
Dalvik VM 和 ART VM 有什么區別
- ART早期使用AOT技術,后期使用AOT+JIT混合,而Dalvik使用JIT
- ART支持64位CPU并兼容32位CPU,而Dalvik只支持32位CPU
- ART對垃圾收集器進行了改進優化,提高了吞吐量。
原文鏈接:https://juejin.cn/post/7089376647576551461
相關推薦
- 2024-04-08 Spring在多線程環境下如何確保事務一致性
- 2022-03-07 Android顯示系統SurfaceFlinger分析_Android
- 2022-10-14 matlab非線性最小二乘擬合
- 2022-01-21 Shell編程:/bin/bash和/bin/sh的區別
- 2022-06-28 C#遞歸算法和排列算法_C#教程
- 2022-05-11 垃圾收集器G1&ZGC詳解
- 2022-03-20 android自定義對話框實例代碼_Android
- 2021-12-02 C語言中幾種常量的認識和理解_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支