- 核心概念:什么是 Android 虚拟机?
- 演进史:从 Dalvik 到 ART
- Dalvik 虚拟机详解
- ART 虚拟机详解
- Dalvik vs. ART 对比
- 开发者需要注意的要点
核心概念:什么是 Android 虚拟机?
一个常见的误解是:Android 运行的是 Java 虚拟机吗?

答案是:不是标准的 JVM,而是 Google 自主设计的一种特殊的虚拟机。
我们可以这样理解整个流程:
- Java 代码:开发者用 Java 语言(或 Kotlin,最终也编译成 Java 字节码)编写 Android 应用。
- 编译成 .class 文件:Java 源代码通过
javac编译器编译成平台无关的 Java 字节码(.class文件)。 - 打包成 .dex 文件:这是 Android 的关键一步,Android 的虚拟机无法直接运行
.class文件,Android SDK 中的dx工具(或构建工具链中的d8/R8)会将所有.class文件转换、优化和合并成一种叫做 Dalvik Executable (.dex) 的文件格式。 - 运行在虚拟机上:这个
.dex文件最终被加载到 Android 设备上的虚拟机中执行。
Android 虚拟机是 Android 系统的核心组件之一,它的职责是:
- 执行应用代码:运行
.dex文件中的应用逻辑。 - 管理内存:负责分配和回收内存,管理应用的生命周期。
- 提供运行时环境:为应用提供核心库和运行时服务。
- 实现应用隔离:每个应用都在自己的虚拟机实例中运行,一个应用的崩溃不会影响到其他应用或系统本身(这是 Android 安全性的基石之一)。
演进史:从 Dalvik 到 ART
Android 虚拟机经历了一次重大的架构升级,这次升级深刻地影响了应用的性能和用户体验。
| 特性 | Dalvik Virtual Machine (DVM) | Android Runtime (ART) |
|---|---|---|
| 首次发布 | Android 1.0 (2008) | Android 4.4 (KitKat, 2025) 作为可选,Android 5.0 (Lollipop, 2025) 成为默认 |
| 核心思想 | 即时编译 | 提前编译 |
| 执行方式 | 应用运行时,虚拟机解释执行 .dex 代码,同时将频繁执行的代码(热点代码)编译成机器码,后续直接执行机器码。 |
在应用安装时,dex2oat 工具就将 .dex 文件预编译成平台相关的机器码(.oat 文件),运行时直接执行这些机器码。 |
| 启动速度 | 较慢,因为首次运行需要边解释边编译。 | 极快,因为应用启动时已经是执行机器码了。 |
| 运行时性能 | 较慢,JIT 需要时间来分析和优化,且优化后的代码只在当前会话有效。 | 非常快,因为所有代码都经过了 AOT 预编译,充分利用了设备的硬件特性(如 ARM 的 NEON 指令集)。 |
| 内存占用 | 较低,JIT 只缓存热点代码,内存占用相对较小。 | 较高,因为 AOT 编译生成了大量机器码,所以编译后的应用包体积和运行时内存占用都比 DVM 大。 |
| 安装/更新时间 | 快,只需解压和复制 .dex 文件。 |
慢,需要执行 dex2oat 进行编译,这个过程会消耗 CPU 和时间。 |
| 电池续航 | 相对较差,频繁的 JIT 编译会消耗 CPU 资源。 | 更好,运行时 CPU 负载降低,减少了电量消耗。 |
| 垃圾回收 | 使用“停止-复制”(Stop-the-World)式的垃圾回收,会导致应用卡顿。 | 使用更先进的并发垃圾回收器(如 CMS, G1),大大减少了应用卡顿。 |
简单比喻:
- Dalvik:像一个“口译员”,你(应用)每次说话(执行代码),他都需要现场翻译(解释执行),但遇到常用的句子(热点代码),他会记住并直接翻译好(JIT 编译),下次再说就快了。
- ART:像一个“笔译员”,在你(应用)开始工作前,他已经把所有你要说的话(
.dex文件)全部翻译成了目标语言(机器码),并写在了纸上(.oat文件),你工作时,直接照着读就行,效率极高。
Dalvik 虚拟机详解
虽然 ART 已经是主流,但了解 DVM 的设计思想有助于理解 ART 的改进。
- 架构:基于寄存器架构,而不是 JVM 的栈架构。
- 寄存器架构:指令直接操作 CPU 寄存器,指令更短,执行效率更高。
- 栈架构:指令操作的是栈中的数据,指令相对冗长。
- 核心文件:
.dex文件,它将多个.class文件合并,共享了常量池,减少了内存占用。 - JIT 编译器:在运行时分析代码,识别“热点方法”(Hot Methods),将它们编译成原生机器码并缓存,下次调用时直接执行机器码,避免了重复的解释开销。
ART 虚拟机详解
ART 是现代 Android 的基石,它解决了 DVM 的主要痛点。
-
AOT 编译:
- 时机:在应用安装、系统更新或应用更新后,由
dex2oat工具完成。 - 过程:读取
.dex文件,结合设备的具体硬件信息(CPU 架构、指令集等),生成高度优化的原生机器码文件(.oat,本质上是包含 ELF 头的 dex 代码和机器码的集合)。 - 优点:运行时性能最大化,启动速度极快。
- 缺点:安装/更新慢,占用更多存储空间。
- 时机:在应用安装、系统更新或应用更新后,由
-
混合编译:
- 为了平衡 AOT 的缺点,Android 引入了混合编译模式。
- 解释执行:对于不常执行的代码(如冷启动时首次调用的方法),ART 会先解释执行,避免为它们花费 AOT 编译的开销。
- JIT (Just-in-Time) / JIT Profiling:ART 仍然保留了 JIT 的能力,在运行时,它会继续收集代码执行信息,识别出新的热点代码,并在后台进行 JIT 编译,将编译结果存入缓存,这被称为“配置文件引导的编译”(Profile-Guided Compilation, PGC)。
- AOT + JIT:结合了 AOT 的初始性能优势和 JIT 的灵活性,实现了更智能的编译策略。
-
高效的垃圾回收:
- ART 的 GC 是并发的,这意味着大部分 GC 工作可以在应用线程运行的同时进行,极大地减少了“卡顿感”(Stop-the-World 的时间显著缩短)。
- 支持多种 GC 算法,可以根据设备性能和内存状况选择最合适的。
Dalvik vs. ART 对比总结
| 特性 | Dalvik | ART |
|---|---|---|
| 编译时机 | 运行时 | 安装时 |
| 编译方式 | JIT (Just-In-Time) | AOT (Ahead-Of-Time) + JIT (辅助) |
| 应用性能 | 较慢 | 非常快 |
| 应用启动速度 | 较慢 | 极快 |
| 安装/更新速度 | 快 | 慢 |
| 存储占用 | 较小 | 较大 |
| 内存占用 | 较小 | 较大 |
| 电池续航 | 较差 | 更好 |
| 垃圾回收 | STW 卡顿严重 | 并发 GC,卡顿少 |
| 当前状态 | 已被完全取代 | 当前 Android 系统的标准运行时 |
开发者需要注意的要点
作为 Android 开发者,你不需要直接编写虚拟机代码,但了解这些知识能帮助你写出更好的应用:
-
构建工具链的演进:
- D8/R8:Google 推出了新的 D8 和 R8 工具来替代旧的
dx和 ProGuard。 - D8:将
.class文件编译成.dex文件,比dx更快、更现代。 - R8:不仅执行 D8 的工作,还集成了代码收缩(ProGuard)、资源收缩和混淆功能,它是你
build.gradle中minifyEnabled true背后的真正执行者。
- D8/R8:Google 推出了新的 D8 和 R8 工具来替代旧的
-
理解 AOT 的影响:
- 安装包体积:你的 APK 包会比在 Dalvik 时代稍大,因为包含了预编译的
.oat文件,这是为了换取运行时性能的合理代价。 - 安装体验:首次安装或更新大型应用时,用户会看到一个“正在优化应用...”的界面,这就是
dex2oat在工作,你需要设计好应用的启动画面,以掩盖这个延迟。
- 安装包体积:你的 APK 包会比在 Dalvik 时代稍大,因为包含了预编译的
-
不要依赖 JIT 的优化:
- 在 Dalvik 时代,开发者有时会利用 JIT 编译来优化循环等热点代码。
- 在 ART 时代,大部分代码在安装时就已经被编译了,你应该专注于编写清晰、高效的代码,而不是试图“戏耍”编译器,ART 的 AOT 编译器比你想象的更聪明。
-
关注启动性能:
- ART 极快的启动速度是一把双刃剑,如果你的应用启动过程耗时过长(比如在主线程进行网络请求、IO 操作或复杂计算),这种“慢”会显得格外突出。优化应用启动时间比以往任何时候都更加重要。
-
混合编译带来的变化:
由于 ART 会解释执行一些冷启动代码,所以你可能会在冷启动时看到一些微小的性能差异,但总体而言,ART 的性能远超 DVM。
- Android 虚拟机不是 JVM,而是 Google 为移动设备设计的特殊虚拟机,核心是执行
.dex文件。 - Dalvik 是过去式,它采用JIT,启动慢、运行时性能一般,但安装快。
- ART 是现在和未来,它采用AOT + 混合编译,启动快、运行时性能极佳、电池续航好,但安装稍慢、占用更多空间。
- 对开发者而言,理解 ART 的工作原理有助于我们优化应用启动时间、理解 APK 体积变化,并写出更符合现代 Android 运行时的高质量代码。
掌握这些知识,你就能从一个只会调 API 的开发者,成长为一名真正理解 Android 平台底层的优秀工程师。
