对比Android的两大运行时环境:Dalvik 和 ART。这次对比不仅会讲技术细节,还会从演进的角度分析它们的设计哲学和实际影响。
一、核心概念与设计哲学
Dalvik:为早期Android设计的虚拟机
诞生时间:Android诞生之初到Android 4.4
设计目标:在资源受限的早期设备(低内存、低CPU性能)上高效运行
核心理念 :JIT编译 + 基于寄存器的架构
ART:面向未来的现代化运行时
诞生时间:Android 4.4(实验性)→ Android 5.0(正式默认)
设计目标:提升性能、流畅度和能效,适应更强大的硬件
核心理念 :AOT编译 + 性能优化优先
二、详细技术对比
对比维度
Dalvik
ART
编译方式
JIT
AOT + JIT(Android 7.0后混合模式)
安装时间
快
较慢 (早期纯AOT版本)→ 优化后接近(混合模式)
应用启动速度
较慢
显著更快
运行时性能
需要实时编译,有性能开销
预编译为本地代码,执行效率高
内存占用
运行时内存占用相对较低
安装后占用更多存储空间(存储odex文件)
电池消耗
运行时编译消耗额外电量
运行时电量消耗更低
垃圾回收
简单的Stop-the-World GC
更先进的并发GC,减少卡顿
架构设计
基于寄存器
基于寄存器(保持兼容)
调试支持
相对简单
提供更丰富的性能分析工具
三、深度技术解析
1. 编译模型的根本差异
Dalvik的JIT工作流程:
复制代码
.dex文件 → 解释执行 → 热点代码识别 → JIT编译为本地代码 → 缓存并执行
优点:安装快,不占用额外存储
缺点:每次启动都需要重新编译热点代码,造成启动慢和运行时卡顿
ART的演进:
a) 初期纯AOT(Android 5.0-6.0):
复制代码
.dex文件 → 安装时完全编译为本地代码 → 直接执行本地代码
优点:运行时性能极佳
缺点:安装时间很长,占用存储空间大
b) 现代混合模式(Android 7.0+):
复制代码
.dex文件 → 安装时快速编译(不优化)→ 解释执行 →
JIT分析热点代码 → 后台AOT优化热点代码
这是目前最智能的模式,平衡了安装速度、运行性能和存储占用。
2. 垃圾回收机制的对比
Dalvik GC的问题:
完全Stop-the-World:GC发生时,所有应用线程暂停
频繁GC:内存管理效率低,导致明显的卡顿
两次暂停:一次标记,一次清理,用户体验差
java
复制代码
// 在Dalvik时代,开发者需要非常小心地避免内存抖动
// 因为频繁GC会导致明显的卡顿
for (int i = 0; i < 10000; i++) {
String temp = new String("item" + i); // 在循环内创建大量对象→频繁GC
// ...
}
ART GC的改进:
并发标记:大部分标记工作与应用线程并发执行
并发清理:减少暂停时间
Generational Collection:分代回收,更高效
更少的暂停:大幅减少卡顿现象
3. 64位支持
Dalvik:主要支持32位
ART:从开始就为64位设计,更好地利用现代CPU架构
四、实际开发影响
对开发者的直接影响
1. 应用性能表现
kotlin
复制代码
// 在ART环境下,以下代码会有更好的性能表现
class MainActivity : AppCompatActivity() {
// 冷启动速度明显提升
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 方法调用在ART中执行更快(已预编译)
initializeViews()
loadData()
}
private fun initializeViews() {
// ART的AOT编译使这些方法调用更高效
recyclerView.layoutManager = LinearLayoutManager(this)
adapter = MyAdapter(createLargeList()) // 大列表操作更流畅
}
private fun createLargeList(): List
// 在ART中,对象创建和垃圾回收更高效
return List(1000) { "Item $it" }
}
}
2. 安装体验变化
Dalvik时代:应用安装飞快,但首次启动慢
ART早期:安装等待时间长,但启动快
ART现代:安装速度优化,兼顾启动性能
3. 调试和优化
bash
复制代码
# ART提供了更好的性能分析工具
adb shell cmd package compile -f -m speed com.example.myapp
# 强制以速度模式编译应用
# 查看编译状态
adb shell dumpsys package dexopt
五、演进历程与现状
历史时间线
Android 1.0-4.4:Dalvik统治时期
Android 4.4:ART作为实验性功能引入
Android 5.0:ART正式取代Dalvik(纯AOT模式)
Android 7.0:引入JIT+ AOT混合模式,解决纯AOT的问题
Android 8.0+:持续优化Profile-guided compilation
Android 10+:对云编译的支持,进一步提升性能
当前现状
Dalvik:已完全被ART取代,仅存在于历史版本中
ART:成为现代Android的基石,持续演进优化
对开发者:大多数情况下无需关心底层差异,ART自动优化
六、总结:为什么ART是必然选择
方面
Dalvik的局限
ART的解决方案
用户体验
启动慢、运行卡顿
启动快、运行流畅
硬件发展
适合早期弱硬件
充分利用现代强大硬件
能效比
运行时编译耗电
预编译节省电量
内存管理
低效GC导致卡顿
并发GC减少暂停
未来准备
32位架构限制
原生64位支持
技术演进启示 : ART取代Dalvik体现了移动计算发展的必然趋势------用存储空间和安装时间换取运行时性能和能效提升。这种权衡在现代硬件条件下是完全合理的,因为存储空间越来越廉价,而用户体验和电池续航始终是核心诉求。
对于Android开发者来说,理解这个演进过程有助于我们:
更好地分析应用性能问题
优化应用启动时间和内存使用
适配不同Android版本的特性
理解Android系统底层的工作原理
ART的胜利标志着Android从"能用"到"好用"的重要转折点。