Android運行時(ART)包括具有代碼概要分析的即時(JIT)編譯器,可在運行時不斷提高Android應用程序的性能。 JIT編譯器對ART當前的提前(AOT)編譯器進行了補充,並提高了運行時性能,節省了存儲空間並加快了應用程序和系統更新的速度。通過避免自動應用程序更新期間的系統速度降低或通過空中(OTA)更新過程中的應用程序重新編譯,它還改進了AOT編譯器。
儘管JIT和AOT使用具有相同優化設置的同一編譯器,但是生成的代碼可能並不相同。 JIT利用運行時類型信息,可以更好地進行內聯,並可以進行堆棧替換(OSR)編譯,所有這些都生成略有不同的代碼。
JIT架構

JIT編譯
JIT編譯涉及以下活動:

- 用戶運行該應用程序,然後觸發ART加載
.dex
文件。- 如果
.oat
文件(.dex
文件的AOT二進製文件)可用,ART將直接使用它。儘管.oat
文件是定期生成的,但它們並不總是包含編譯後的代碼(AOT二進製文件)。 - 如果
.oat
文件不包含已編譯的代碼,則ART將通過JIT和解釋器運行以執行.dex
文件。
- 如果
- 對於未根據
speed
編譯過濾器編譯的任何應用程序都啟用了JIT(它表示“可以從該應用程序中進行盡可能多的編譯”)。 - JIT概要文件數據將轉儲到僅應用程序可以訪問的系統目錄中的文件中。
- AOT編譯(
dex2oat
)守護程序解析該文件以驅動其編譯。圖3. JIT守護程序活動。
Google Play服務是其他應用程序使用的示例,這些應用程序的行為類似於共享庫。
JIT工作流程

- 分析信息存儲在代碼緩存中,並在內存壓力下進行垃圾回收。
- 無法保證當應用程序在後台時拍攝的快照將包含完整的數據(即,所有被JIT處理的數據)。
- 沒有嘗試確保記錄所有內容(因為這可能會影響運行時性能)。
- 方法可以處於三種不同的狀態:
- 解釋(dex代碼)
- JIT編譯
- AOT編譯
- 在不影響前台應用程序性能的情況下運行JIT的內存要求取決於所討論的應用程序。大型應用程序比小型應用程序需要更多的內存。通常,大型應用程序穩定在4 MB左右。
開啟JIT記錄
要打開JIT日誌記錄,請運行以下命令:
adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts -verbose:jit
adb shell start
禁用JIT
要禁用JIT,請運行以下命令:
adb root
adb shell stop
adb shell setprop dalvik.vm.usejit false
adb shell start
強制編譯
要強制編譯,請運行以下命令:
adb shell cmd package compile
強制編譯特定程序包的常見用例:
- 基於個人資料:
adb shell cmd package compile -m speed-profile -f my-package
- 完整:
adb shell cmd package compile -m speed -f my-package
強制編譯所有軟件包的常見用例:
- 基於配置文件:
adb shell cmd package compile -m speed-profile -f -a
- 完整:
adb shell cmd package compile -m speed -f -a
清除個人資料數據
要清除概要文件數據並除去編譯的代碼,請運行以下命令:
- 對於一個軟件包:
adb shell cmd package compile --reset my-package
- 對於所有軟件包:
adb shell cmd package compile --reset -a