ART、JIT、AOT、Dalvik之间有什么关系?

110 阅读3分钟

这几个名词都跟 Android 应用代码的执行方式 有关,其实是不同阶段/不同版本 Android 在虚拟机和编译策略上的演进。

1. Dalvik

  • 定义:Android 最早(~Android 4.x 及以前)使用的虚拟机,专门为内存和性能受限的移动设备优化。

  • 核心特性

    • 基于 寄存器架构(相比 JVM 的栈架构,减少指令数和内存访问)
    • .dex 文件(Dalvik Executable)为多 class 合并后的字节码格式
  • 执行模式

    • 主要依赖 JIT(Just-In-Time)即时编译:应用运行时,将热点字节码编译为机器码并缓存
    • 首次运行时会有冷启动延迟,且多次运行同样代码仍需重复编译

2. JIT(Just-In-Time)

  • 定义:运行时才编译,按需将热点字节码转为机器码

  • 优点

    • 启动快(不用提前编译整个应用)
    • 编译开销分散到运行过程中
  • 缺点

    • 运行期间 CPU 负担重(编译线程与业务线程竞争资源)
    • 代码重复运行时可能需要再次编译
  • 在 Dalvik 中:是唯一编译方式

  • 在 ART(Android Runtime)中:Android 7.0 引入 JIT + AOT 混合模式


3. ART(Android Runtime)

  • 定义:Android 5.0(Lollipop)开始替代 Dalvik 的新运行时环境

  • 重大变化

    • 采用 AOT(Ahead-Of-Time)预编译:安装 APK 时,直接把 .dex 编译成机器码(.oat 文件),存储在 /data/dalvik-cache/
    • 优点:运行时无需解释执行,性能大幅提升;减少 GC 频率
    • 缺点:安装时间长,占用更多存储空间
  • 演进

    • Android 7.0:改为 JIT + AOT 混合编译,安装时不全部 AOT,而是运行中 JIT 热点方法,后台空闲时 Profile-Guided AOT 编译
    • Android 9+ :JIT Profile 数据可通过 Google Play 预热下发,加快首次启动性能

4. AOT(Ahead-Of-Time)

  • 定义:在运行前(安装时)一次性把字节码编译为机器码

  • 优点

    • 运行时性能高、耗电低(少了编译的 CPU 消耗)
    • 减少 GC 停顿(编译器可优化内存分配)
  • 缺点

    • 安装时间长(大应用可明显感知)
    • 占用更多存储(机器码体积 > 字节码)
  • 在 ART 中

    • Android 5–6:纯 AOT
    • Android 7+:JIT 热点方法 + 空闲时增量 AOT

5. 关系总结(时间线)

scss
复制编辑
Dalvik (<= Android 4.x) —— JIT 为主
        ↓
ART 初代 (Android 5.06.0) —— 纯 AOT
        ↓
ART 混合模式 (Android 7.0+) —— JIT 热点 + Profile 指引的 AOT

一句话记忆

  • Dalvik = 老虚拟机,只会 JIT
  • ART = 新虚拟机,引入 AOT(5.0纯AOT,7.0起混合模式)
  • JIT = 运行时编译,启动快但运行期耗 CPU
  • AOT = 安装时编译,运行快但安装慢/占存储

JIT 与 AOT 对比

特性JIT(即时编译)AOT(预编译)
编译时机运行时安装时
启动速度
长时间运行性能一般(需重复编译)高(直接执行机器码)
安装耗时
存储空间占用
灵活性高(可适配动态代码)

总结

Android 最早用的是 Dalvik 虚拟机,执行 .dex 字节码,靠 JIT 即时编译热点代码;5.0 开始换成 ART,首次采用纯 AOT 预编译,把字节码在安装时转成机器码,运行效率高但安装慢。到 7.0 后,ART 改为 JIT + AOT 混合模式,用运行中收集的 Profile 数据做增量 AOT,兼顾启动速度和运行性能。