主要记录Android Dalvik和ART虚拟机相关的概念、历史、发展、对比。
关键概念
- Dalvik:
- Android早期使用的虚拟机(Android 5.0之前),使用JIT编译方案。
- 文件格式dex
- ART:Android runtime
- 现在普遍使用的虚拟机(Android5.0及之后),使用AOT编译方案。
- Android7.0之后,采用AOT\JIT混合的编译方案。
- JIT:Just In Time
- 程序运行时,实时将字节码编译为机器代码并执行。
- AOT:Ahead Of Time
- 在软件安装的时候就把字节码码编译成机器代码。
- DEX:
- 专为Android平台设计的一种压缩的执行格式。
- DEX文件在应用的构建过程中产生。
- OAT:
- 在ART环境中使用的编译后的执行文件格式,包含了从DEX文件预编译的本地机器代码。
两种虚拟机
Dalvik虚拟机
简介
- Android的首个版本就开始使用的虚拟机,即2008年发布的Android 1.0。
- Dalvik是专门为Android系统设计的虚拟机。
- 主要是为了优化电池续航和提升在有限内存的设备上的运行效率。
特点
- 基于寄存器:
- Dalvik虚拟机是一个基于寄存器的虚拟机。
- 相比基于栈的虚拟机(JVM),基于寄存器的设计可以减少指令的数量,从而提高执行效率。
- JIT编译:
- Dalvik在Android 2.2 (Froyo) 引入了即时编译(JIT),允许应用运行时将频繁执行的代码部分编译成本地代码,这样可以提高应用的执行速度。
Android Runtime (ART)
简介
- 引入:ART首次引入是在Android 4.4 (KitKat) 。
- 夺权:在Android 5.0 (Lollipop) 中,ART取代了Dalvik,成为了默认的运行环境。
- 回归:在Android 7.0(Nougat),JIT 编译器回归,形成 AOT/JIT 混合编译模式。
- 目的:为了进一步提升应用的性能、减少应用启动时间和系统占用。
特点
- AOT编译:
- 与Dalvik的JIT编译不同,ART采用了提前编译(AOT,Ahead-of-Time Compilation)。
- 在应用安装时,ART将全部字节码转换成机器码,这一过程增加了应用的安装时间,但显著减少了运行时的CPU负载和启动时间。
- 改进的垃圾回收:
- 大多采用并发设计,只有一次 GC 暂停(Dalvik 需要两次)。
- 并发复制,可减少后台内存使用和碎片
- GC 暂停的时间不受堆大小影响
- 在清理最近分配的短时对象这种特殊情况中,回收器的总 GC 时间更短
- 更好的内存分配和管理:
- ART使用了更加高效的内存分配策略,提高了性能并减少了内存浪费。
作用流程

编译方案
JIT
- 引入原因:
- 在Android 2.2 (Froyo) 之前,Dalvik虚拟机完全依赖于解释执行字节码,这意味着每次运行程序时都需要读取并解释字节码,这会导致性能的下降。
- 特点:
- 动态编译:应用代码在运行时根据需要被编译成机器语言。
- 热点代码优化:JIT编译可以在应用运行时将经常执行的字节码部分(热点代码)编译成本地代码,从而减少解释执行的开销,以提高应用的运行速度。
AOT
- 引入原因:
- 为了提高应用的性能,尤其是在应用启动时。通过提前编译,应用可以更快地启动并运行,改善用户体验。
- 特点:
- 启动性能:由于代码已经被编译成机器语言,应用程序在启动时无需等待编译,从而减少了启动时间。
- 运行开销:运行时无需进行额外的编译,因此可以减少CPU的使用和电池消耗。
- 安装、存储开销:增加应用的安装时间和生成的可执行文件大小。
DEX和OAT
DEX文件(Dalvik Executable)
定义
- 是Android应用程序中使用的一种压缩的执行格式,专为Android平台设计。
生成时机及过程
- 时机:
- 应用的编译阶段生成的。
- 过程:
- 首先将Java源代码编译成Java字节码(即.class文件)。
- 然后使用Android SDK中的“dx”工具(或Android Studio内置的构建工具)将.class文件转换成一个或多个DEX文件。
- 将生成的DEX文件打包进APK中。
作用阶段
- 对于Dalvik虚拟机,DEX文件在应用运行时被加载,通过解释执行或JIT编译执行。
- 对于ART虚拟机,DEX文件在应用安装时被预编译成OAT格式。
OAT文件(Android Runtime Executable)
定义
- 是在ART环境中使用的编译后的执行文件格式,包含了从DEX文件预编译的本地机器代码。
- 包含的机器代码是针对设备优化过的。
生成时机及过程
- 时机:应用安装过程中生成的。
- 过程:
- 当应用安装时,ART虚拟机会在首次安装期间将DEX文件编译成OAT文件。
作用阶段
- 应用启动和运行阶段起作用。
特点
- 由于OAT文件包含预编译的本地代码,它允许ART虚拟机直接执行这些代码,无需在运行时进行任何额外编译,从而提高应用的性能和响应速度。
对比总结
虚拟机对比
ㅤ | Dalvik 虚拟机 | Android Runtime (ART) |
编译方式 | JIT(即时编译) | AOT(提前编译),从Android 6.0起结合JIT |
优势 | 内存和存储占用较低 | 只有一次 GC 暂停 |
ㅤ | 应用安装时间短 | 支持更好的垃圾回收机制 |
缺陷 | 运行时性能不及ART | 安装应用时需要更多时间 |
ㅤ | 随着应用复杂度增加,性能劣势更明显 | 占用更多的存储空间 |
引入时间 | Android 1.0 (2008) | Android 4.4 (KitKat) 作为实验性选择 |
ㅤ | Android 5.0被ART取代 | Android 5.0 (Lollipop) 正式默认虚拟机 |
目的 | 为低性能硬件优化,提高电池续航 | 进一步提升应用性能,优化用户体验 |
基本原理 | 基于寄存器,减少指令数量 | 全部字节码转换成机器码,优化执行速度 |
ㅤ | ㅤ | 优化内存管理和应用响应速度 |
编译方案对比
ㅤ | AOT编译 | JIT编译 |
编译时机 | 在应用安装时完成编译 | 在应用运行时进行编译 |
优势 | 提升应用的启动速度 | 不需要在安装时进行大量编译 |
ㅤ | 减少应用运行时的CPU和内存负担 | 节省存储空间,因为不需存储大量编译后的代码 |
ㅤ | 更稳定的性能,因为编译是提前完成的 | 可以针对用户的使用模式进行优化 |
ㅤ | ㅤ | 能够适应不同硬件和运行时条件 |
劣势 | 增加应用的安装时间 | 可能导致应用初次启动时性能较低 |
ㅤ | 占用更多的存储空间,因为编译的代码会被存储 | 需要不断编译,增加运行时CPU的负担 |
ㅤ | ㅤ | 性能波动,因为编译发生在运行时 |
适用场景 | 性能敏感型应用 | 开发阶段和测试阶段,迭代快的应用 |
ㅤ | 需要快速启动的应用 | 资源受限的设备 |
复杂度 | 需要复杂的编译器技术,能分析和优化整个应用 | 较为简单,实时根据应用行为作出编译决策 |
AOT和JIT对比
ㅤ | AOT编译 | JIT编译 |
编译时机 | 应用安装前,全部代码一次性编译 | 应用运行时,根据需要编译 |
优点 | 提高应用启动速度,运行时性能稳定 | 节省空间,适应性强,优化应用运行性能(相对于没有引入JIT而言) |
缺点 | 增大文件大小,延长应用安装时间 | 初次运行慢,运行时CPU和内存使用可能增加 |
主要用途 | 性能敏感应用,需要快速响应的场景 | 开发和测试阶段,资源受限的设备 |
DEX和OAT对比
ㅤ | DEX 文件 | OAT 文件 |
定义 | Dalvik Executable 文件,包含编译后的Java类的字节码。 | Android Runtime Executable 文件,包含可以直接运行的本地机器代码。 |
文件格式 | .dex | .oat |
产生时机 | 在应用打包阶段,将.class文件转换为.dex文件。 | 在应用安装阶段,ART将.dex文件编译成.oat文件。 |
作用 | 在Dalvik虚拟机中,用于运行时解释执行或JIT编译。 | 在ART虚拟机中,用于提供已经编译和优化的代码,直接执行以提高性能。 |
性能 | 解释执行或JIT编译可能导致性能波动。 | 由于代码已预编译,提供更快的执行速度和更短的启动时间。 |
优化级别 | 较低,因为DEX主要依赖虚拟机在运行时的解释或即时编译。 | 较高,OAT文件在安装时已针对具体硬件进行优化。 |
存储与安装 | 文件体积相对较小。 | 文件体积较大,因为包含了为设备优化后的完整机器代码。 |
兼容性 | 主要用于旧的Android系统和Dalvik虚拟机。 | 专为Android Runtime(ART)设计,用于现代Android系统。 |
参考/资料
- Author:CoderWdd
- URL:https://www.wuinsights.top//article/01HW864M3X91FPP3PC2BWW0RBZ
- Copyright:All articles in this blog, except for special statements, adopt BY-NC-SA agreement. Please indicate the source!
Relate Posts