ART 执行模式:解释、JIT 与 AOT
2026/8/9大约 3 分钟运行时Android 14ARTJITAOT
ART 执行模式:解释、JIT 与 AOT
上一章看了编译产物。这一章回答:解释、JIT、AOT 有什么区别,ART 如何选择,profile 如何指导执行?
解释、JIT 与 AOT 会组合使用
| 常见误解 | 正确理解 |
|---|---|
| 应用要么解释要么编译 | 三种模式动态组合,按 profile 切换 |
| JIT 会拖慢启动 | JIT 只编热点,配合解释启动反而快 |
| AOT 一次编译永久最优 | profile 变化后仍需重新编译热点 |
核心结论
- 解释器提供即时执行,避免等待编译。
- JIT 收集 profile 并编译热点方法。
- AOT 按 profile 或全量预编译。
- 执行路径动态切换:解释 → JIT → AOT 产物复用。
- 冷启动优化常围绕 profile 与 AOT 配合。
执行模式主链
逐步解释:
- 开始:方法先解释执行。
- 热点:频繁方法被 JIT 编译。
- 记录:profile 记录热点。
- 预编译:AOT 按 profile 生成代码。
- 选择:运行时按情况走解释或编译代码。
为什么 JIT 不拖慢启动
JIT 只编译“热点”,启动阶段大部分方法走解释器,编译在后台/按需进行。这样启动快, 运行期热点又能获得编译优化,配合 AOT 实现“启动快 + 运行快”。
源码证据
阅读目标:确认执行模式入口。
正文指针:art/runtime/interpreter/(解释器);art/runtime/jit/(JIT); art/runtime/oat/(AOT 加载)。
// art/runtime/(伪代码,行号以 r75 为准)
// 方法入口根据编译状态选择解释器或编译代码这段代码证明: 方法执行路径由编译状态决定;JIT/AOT 产物都在运行时统一调度。
验证与排障
环境:开发设备或模拟器;以下命令不需要 root。
adb shell cmd package compile -m speed-profile <包名>
adb logcat -v threadtime | grep -E "JIT|jit|Compile"
adb shell dumpsys package <包名> | grep -E "codePath"切换编译策略对比启动与性能;logcat 看 JIT/编译活动。执行性能波动时,先确认 编译策略与 profile 是否匹配实际热点。
常见误区
- “解释或编译二选一”:混合模型。
- “JIT 一定拖慢启动”:只编热点。
- “AOT 永远最优”:profile 变化需重新编译。
- “性能问题都是执行模式”:先确认编译状态再说。
延伸问题
- profile 的收集与回写机制是什么?
- 启动路径与运行热点的编译差异是什么?
- 如何验证 JIT 对性能的实际影响?
- 不同设备/ABI 的执行差异在哪里?
源码入口
| 文件 | 关键位置 | 作用 |
|---|---|---|
art/runtime/interpreter/ | 解释器 | 即时执行 |
art/runtime/jit/ | JIT | 热点编译 |
art/runtime/oat/ | AOT | 预编译加载 |
cmd package compile | 命令行 | 策略 |
公共路径:art/。行号以 r75 检索为准。
执行过程中对象如何回收,见 ART GC。