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