Android 運行時 (ART) 包括一個即時 (JIT) 編譯器,該編譯器具有代碼分析功能,可在 Android 應用程序運行時不斷提高它們的性能。 JIT 編譯器補充了 ART 當前的提前 (AOT) 編譯器,提高了運行時性能,節省了存儲空間,並加速了應用程序和系統更新。它還通過避免在自動應用程序更新期間系統減速或在無線 (OTA) 更新期間重新編譯應用程序來改進 AOT 編譯器。
儘管 JIT 和 AOT 使用具有相似優化集的相同編譯器,但生成的代碼可能並不相同。 JIT 利用運行時類型信息,可以進行更好的內聯,並使堆棧替換 (OSR) 編譯成為可能,所有這些都會生成略有不同的代碼。
即時架構
即時編譯
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 代碼)
- 即時編譯
- 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