自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
实现 ART 即时编译器
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
Android Runtime (ART) 包含一个具备代码分析功能的即时 (JIT) 编译器,该编译器可以在 Android 应用运行时持续提高其性能。JIT 编译器对 Android 运行组件当前的预先 (AOT) 编译器进行了补充,可以提升运行时性能,节省存储空间,加快应用和系统更新速度。相较于 AOT 编译器,JIT 编译器的优势也更为明显,因为在应用自动更新期间或在无线下载 (OTA) 更新期间重新编译应用时,它不会拖慢系统速度。
尽管 JIT 和 AOT 使用相同的编译器,它们所进行的一系列优化也较为相似,但它们生成的代码可能会有所不同。JIT 会利用运行时类型信息,可以更高效地进行内联,并可让堆栈替换 (OSR) 编译成为可能,而这一切都会使其生成的代码略有不同。
JIT 架构
图 1. JIT 架构。JIT 编译
JIT 编译涉及以下活动:
图 2. 配置文件引导的编译。
- 用户运行应用,此举随后触发 ART 加载
.dex
文件。- 如果有
.oat
文件(即 .dex
文件的 AOT 二进制文件),ART 会直接使用该文件。虽然 .oat
文件会定期生成,但文件中不一定会包含经过编译的代码(即 AOT 二进制文件)。
- 如果
.oat
文件不含经过编译的代码,ART 会通过 JIT 和解释器执行 .dex
文件。
- 针对任何未根据
speed
编译过滤器编译的应用启用 JIT(也就是说,要尽可能多地编译应用中的代码)。
- 将 JIT 配置文件数据转储到只有该应用可以访问的系统目录下的文件中。
- AOT 编译 (
dex2oat
) 守护程序通过解析该文件来推进其编译。
图 3. JIT 守护程序 activity。
举例来说,Google Play 服务就是一种由其他应用使用的类似于共享库的服务。
JIT 工作流程
图 4. JIT 数据流。
- 分析信息会存储在代码缓存中,并会在内存紧张时作为垃圾被回收。
- 无法保证在应用处于后台运行状态时所捕获的快照能够包含完整的数据(即 JIT 编译的所有内容)。
- 该过程不会尝试确保记录所有内容(因为这会影响运行时性能)。
- 方法可能有三种不同的状态:
- 已经过解释(dex 代码)
- 已经过 JIT 编译
- 已经过 AOT 编译
如果同时存在 JIT 和 AOT 代码(例如,由于反复进行逆优化),经过 JIT 编译的代码将是首选代码。
- 在不影响前台应用性能的情况下运行 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
清除配置文件数据
在 Android 13 或更低版本中
如需清除本地配置文件数据并移除经过编译的代码,请运行以下命令:
adb shell pm compile --reset
在 Android 14 或更高版本中
若要仅清除本地配置文件数据,请执行以下操作:
adb shell pm art clear-app-profiles
注意:与适用于 Android 13 或更低版本的命令不同,此命令不会清除随应用一起安装的外部配置文件数据(“.dm”)。
如需清除本地配置文件数据并移除根据本地配置文件数据生成的已编译代码(即重置安装状态),请运行以下命令:
adb shell pm compile --reset
注意:此命令不会移除随应用一起安装的外部配置文件数据(“.dm”)生成的已编译代码。
如需清除所有已编译代码,请运行以下命令:
adb shell cmd package compile -m verify -f
注意:此命令会保留本地配置文件数据。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-03-03。
[[["易于理解","easyToUnderstand","thumb-up"],["解决了我的问题","solvedMyProblem","thumb-up"],["其他","otherUp","thumb-up"]],[["没有我需要的信息","missingTheInformationINeed","thumb-down"],["太复杂/步骤太多","tooComplicatedTooManySteps","thumb-down"],["内容需要更新","outOfDate","thumb-down"],["翻译问题","translationIssue","thumb-down"],["示例/代码问题","samplesCodeIssue","thumb-down"],["其他","otherDown","thumb-down"]],["最后更新时间 (UTC):2025-03-03。"],[],[],null,["# Implement ART just-in-time compiler\n\nAndroid runtime (ART) includes a just-in-time (JIT) compiler with code profiling\nthat continually improves the performance of Android applications as they run.\nThe JIT compiler complements ART's current ahead-of-time (AOT) compiler and\nimproves runtime performance, saves storage space, and speeds application and\nsystem updates. It also improves upon the AOT compiler by avoiding system\nslowdown during automatic application updates or recompilation of applications\nduring over-the-air (OTA) updates.\n\n\nAlthough JIT and AOT use the same compiler with a similar set of optimizations,\nthe generated code might not be identical. JIT makes use of runtime type\ninformation, can do better inlining, and makes on stack replacement (OSR)\ncompilation possible, all of which generates slightly different code.\n\nJIT architecture\n----------------\n\n**Figure 1.** JIT architecture.\n\nJIT compilation\n---------------\n\nJIT compilation involves the following activities:\n**Figure 2.** Profile-guided compilation.\n\n1. The user runs the app, which then triggers ART to load the `.dex` file.\n - If the `.oat` file (the AOT binary for the `.dex` file) is available, ART uses it directly. Although `.oat` files are generated regularly, they don't always contain compiled code (AOT binary).\n - If the `.oat` file does not contain compiled code, ART runs through JIT and the interpreter to execute the `.dex` file.\n2. JIT is enabled for any application that is not compiled according to the `speed` compilation filter (which says \"compile as much as you can from the app\").\n3. The JIT profile data is dumped to a file in a system directory that only the application can access.\n4. The AOT compilation (`dex2oat`) daemon parses that file to drive its compilation. \n\n **Figure 3.** JIT daemon activities.\n\n\nThe Google Play service is an example used by other applications that behave\nsimilar to shared libraries.\n\nJIT workflow\n------------\n\n**Figure 4.** JIT data flow.\n\n- Profiling information is stored in the code cache and subjected to garbage collection under memory pressure.\n - There is no guarantee a snapshot taken when the application was in the background will contain complete data (i.e., everything that was JITed).\n - There is no attempt to ensure everything is recorded (as this can impact runtime performance).\n- Methods can be in three different states:\n - interpreted (dex code)\n - JIT compiled\n - AOT compiled\n If both JIT and AOT code exists (e.g. due to repeated de-optimizations), the JITed code is preferred.\n- The memory requirement to run JIT without impacting foreground app performance depends upon the app in question. Large apps require more memory than small apps. In general, large apps stabilize around 4 MB.\n\nTurn on JIT logging\n-------------------\n\nTo turn on JIT logging, run the following commands: \n\n adb root\n adb shell stop\n adb shell setprop dalvik.vm.extra-opts -verbose:jit\n adb shell start\n\nDisable JIT\n-----------\n\nTo disable JIT, run the following commands: \n\n adb root\n adb shell stop\n adb shell setprop dalvik.vm.usejit false\n adb shell start\n\nForce compilation\n-----------------\n\nTo force compilation, run the following: \n\n```\nadb shell cmd package compile\n```\n\nCommon use cases for force compiling a specific package:\n\n- Profile-based: \n\n ```\n adb shell cmd package compile -m speed-profile -f my-package\n ```\n- Full: \n\n ```\n adb shell cmd package compile -m speed -f my-package\n ```\n\nCommon use cases for force compiling all packages:\n\n- Profile-based: \n\n ```\n adb shell cmd package compile -m speed-profile -f -a\n ```\n- Full: \n\n ```\n adb shell cmd package compile -m speed -f -a\n ```\n\nClear profile data\n------------------\n\n### On Android 13 or earlier\n\nTo clear local profile data and remove compiled code, run the following: \n\n```\nadb shell pm compile --reset \n```\n\n### On Android 14 or later\n\nTo clear local profile data only: \n\n```\nadb shell pm art clear-app-profiles \n```\n\nNote: Unlike the command for Android 13\nor earlier, this command doesn't clear external profile data (\\`.dm\\`) that is\ninstalled with the app.\n\nTo clear local profile data and remove compiled code generated from local\nprofile data (i.e., to reset to the install state), run the following: \n\n```\nadb shell pm compile --reset \n```\n\nNote: This command doesn't remove compiled code generated from\nexternal profile data (\\`.dm\\`) that is installed with the app.\n\nTo clear all compiled code, run this command: \n\n```\nadb shell cmd package compile -m verify -f \n```\n\nNote: This command retains local profile data."]]