Art & Dalvik 及其区别
摘要
Dalvik,ART是Android的两种运行环境,也可以叫做Android虚拟机。
JIT,AOT是Android虚拟机采用的两种不同的编译策略
在Dalvik虚拟机上,APK中的Dex文件在安装时会被优化成odex文件,在运行时,会被JIT编译器编译成native代
码。
在ART虚拟机上安装时,Dex文件会直接由dex2oat工具翻译成oat格式的文件,oat文件中既包含了dex文件中原
先的内容,也包含了已经编译好的native代码。
Dalvik
Dalvik 虚拟机(Dalvik Virtual Machine),简称 Dalvik VM 或者 DVM。它是 Google 专门为 Android 平台开发的虚拟机,运行在 Android 运行时库中。
-
原理
一个应用首先经过DX工具将class文件转换成Dalvik虚拟机可以执行的dex文件,然后由类加载器加载原生类和
Java类。Dalvik虚拟机负责解释器根据指令集对Dalvik字节码进行释dex文件为机器码。 -
JIT编译器
Dalvik负责将dex翻译为机器码交由系统调用,有一个缺陷,每次执行代码,都需要Dalvik将操作码代码翻译为
机器对应的微处理器指令,然后交给底层系统处理,运行效率很低。
JIT编译器,当App运行时,每当遇到一个新类,JIT编译器就会对这个类进行即时编译,经过编译后的代码,会被
优化成相当精简的原生型指令码(即native code),这样在下次执行到相同逻辑的时候,速度就会更快。 -
Dalvik的启动流程
Dalvik进程管理是依赖于linux的进程体系结构的,如要为应用程序创建一个进程,它会使用linux的fork机制来
复制一个进程。
ART
- 原理
JIT是运行时编译,这样可以对执行次数频繁的dex代码进行编译和优化,减少以后使用时的翻译时间, 但将dex
翻译为本地机器码也要占用时间,所以Google在4.4之后推出了ART,用来替换Dalvik。
ART的策略与Dalvik不同,在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为
真正的本地应用。之后打开App的时候,不需要额外的翻译工作,直接使用本地机器码运行,因此运行速度提高。 - AOT
AOT 是静态编译,应用在安装的时候会启动 dex2oat 过程把 dex预编译成 ELF 文件,每次运行程序的时候不用
重新编译。
总结
- JIT编译器
从 Android 2.2 版本开始 DVM 使用了 JIT 编译器,它会对多次运行的代码(热点代码)进行编译,生成精简的本地机器码(Native Code),这样在下次执行到相同代码时,可以直接使用机器码执行。但是,应用程序每次重新运行时,都需要做 JIT 编译工作。
- ART
ART(Android Runtime)虚拟机是 Android 4.4 发布的,用来替换 Dalvik 虚拟机,Android 4.4 默认采用 DVM,但是可以选择使用 ART。在 Android 5.0 版本中默认使用 ART,DVM 从此退出历史舞台。
- AOT预编译
DVM 中的应用每次运行时,字节码搜需要通过 JIT 编译器编译成机器码,这会使得应用程序的运行效率降低。而在 ART 中,系统在安装应用程序时会进行一次 AOT(ahead of time compilation, 预编译),将字节码预先编译成机器码并存储在本地,这样应用程序每次运行时就不需要执行编译了,运行 效率会大大提升,设备的耗电量也会降低。
不过采用 AOT 也有缺点
AOT 会使得应用程序的安装时间变长,尤其是一些复杂的应用
字节码预先编译成机器码,机器码需要的存储空间会多一些
为了弥补以上两个缺点,Android 7.0 版本的 ART 加入了即时编译器 JIT,作为 AOT 的一个补充,在应用程序安装时不会将字节码全部编译成机器码,而是在运行种将热点代码编译成机器码,从而缩短了应用程序的安装时间并节省了存储空间。
- ART 与 DVM
DVM 使用JIT,ART使用AOT+JIT(Android7.0之后混合使用,Android5.0-Android7.0之前使用AOT )
DVM 时为 32 位 CPU 设计的,而 ART 支持 64 位并兼容 32 位 CPU,这也是 DVM 被淘汰的主要原因之一。
ART 对垃圾回收机制进行了改进,比如更频繁地执行并行垃圾收集,将 GC 暂停由 2 次减少为 1 次等
Java 虚拟机、Art、Dalvik 他们的区别