1. 程式人生 > >為什麼應用程式在Android 7.0之後安裝和執行都變得更快?

為什麼應用程式在Android 7.0之後安裝和執行都變得更快?

需要了解幾個概念

  • Dalvik 虛擬機器

負責解釋dex檔案為機器碼,每次執行程式碼,都需要Dalvik將dex程式碼翻譯為微處理器指令,然後交給系統處理,這樣效率不高。

  • JIT(Just-In-Time)

為了解決上面的問題,Google在2.2版本添加了JIT編譯器,當App執行時,每當遇到一個新類,JIT編譯器就會對這個類進行編譯,經過編譯後的程式碼,會被優化成相當精簡的原生型指令碼(即native code),這樣在下次執行到相同邏輯的時候,速度就會更快。

當然使用JIT也不一定加快執行速度,如果大部分程式碼的執行次數很少,那麼編譯花費的時間不一定少於執行dex的時間。所以JIT不對所有dex程式碼進行編譯,而是隻編譯執行次數較多的dex為本地機器碼。

有一點需要注意,dex位元組碼翻譯成本地機器碼是發生在應用程式的執行過程中的,並且應用程式每一次重新執行的時候,都要做重做這個翻譯工作,所以這個工作並不是一勞永逸,每次重新開啟App,都需要進行JIT編譯。

對執行次數頻繁的dex程式碼進行編譯和優化,減少以後使用時的翻譯時間,雖然可以加快Dalvik執行速度,但是還是有弊病,那就是將dex翻譯為本地機器碼也要佔用時間

  • ART 虛擬機器

與Dalvik不同,在ART 環境中,應用在第一次安裝的時候,位元組碼就會預先編譯成機器碼,使其成為真正的本地應用。之後開啟App的時候,直接使用本地機器碼執行,因此執行速度提高。

ART需要應用程式在安裝時,就把程式程式碼轉換成機器語言,所以這會消耗掉更多的儲存空間,但消耗掉空間的增幅通常不會超過應用程式碼包大小的20%。由於有了一個轉碼的過程,所以應用安裝時間難免會延長

  • AOT

對比JIT就很好理解了,一個是執行時編譯,一個是安裝時編譯。

使用JIT編譯器時,App優缺點

  • 優點

  • 安裝迅速

  • 安裝時所需容量小

  • 缺點

  • 使用了JIT,在執行時編譯,導致電量消耗快

  • JIT本身也有開銷

使用AOT編譯器的時候,App優缺點

  • 優點

  • 啟動快

  • 執行快(不卡頓),因為直接執行的機器碼

  • 電量消耗少,沒有了JIT

  • 缺點

  • 安裝慢,因為安裝的時候需要將 .dex 編譯成本地機器碼。

  • 需要更大的安裝空間,因為將 .dex 編譯成機器碼之後,需要儲存起來。

AOT編譯方案面臨的挑戰

由於系統更新時,所有的應用都需要重新安裝,這會導致所有的應用都需要在重新編譯一遍,如果你的應用賊多的話……。

編譯之後的native code會比較大,消耗了儲存空間,如果你的應用非常大的話,一些小容量的手機可能無法安裝。

這中編譯行為對動態apk的支援不是很好。

可以看到,JIT與AOT的優缺點完全是反過來的,Google大佬就將這兩個方案結合起來,整出了混合編譯。

Google大佬的解決方案,混合編譯發現JIT又回來了。

當用戶安裝App的時候,不再進行預編譯了,這個和KitKat的時候一樣。當用戶安裝之後立即使用該App,仍然使用JIT編譯模式來執行App,但是同時會生成一個離線的 profile 檔案,這個 profile 檔案會記錄JIT執行時的所有 hot code(熱點程式碼)資訊。然後在未來的某個時間點,Android Framework 會基於這個 profile 檔案來啟動一個預編譯行為,它只便於記錄的熱點程式碼。

在 JIT 階段,它帶來的好處:

  • 快速安裝

  • 系統快速更新

在 AOT 階段,它帶來的好處:

  • 快速啟動,更好的執行效能

  • 低消耗:CPU,儲存空間,電量…

ART混合編譯模式

  • 一些使用者只使用App中的一部分功能,只有這些被頻繁使用的部分(這個功能涉及到的程式碼)才值得被編譯成 native code。

  • 在 JIT 階段,我們可以很容易的找到經常被使用的程式碼。

  • 使用 AOT 來加快這些經常使用的用例。

  • 避免在一些基本不適用的程式碼上花費開銷。

混合編譯與AOT的效能比較

有意思的是,AOT與JIT在Micro Benchmark測試中各有優劣。

參考文件如下所示:

https://www.youtube.com/watch?v=TCJLFqhC1VE

https://www.cnblogs.com/keyarchen/p/6063096.html