走近 Android 运行时: DVM VS ART

原文作者: Ankit Sinhal

原文地址:Closer Look At Android Runtime: DVM vs ART

译者: sunluyao

dalvik_vs_art

在学习 Android Runtime(运行时)之前,我们需要了解什么是运行时环境并且了解一些基本知识,例如 JVM(Java虚拟机)和 Dalvik VM(Dalvik虚拟机)的功能。

什么是 runtime(运行时)?

简而言之,它就是一个系统,它关心的是将你使用高级语言(比如Java)编写的代码转化为 CPU/处理器可以理解的机器代码。

运行时包含当你的程序运行时的软件说明,即使它们基本上不是软件的一部分。

CPU 或者更普遍的我们的电脑仅仅只理解机器语言(二进制代码)。所以为了使之可以在 CPU 上运行,代码必须被转化为机器代码,这是通过解释器来实现的。

下面是几个解释器:

1. Assemblers(汇编器)

它直接将汇编代码解释成机器代码,所以它的速度非常快。

2. Compilers(编译器)

它先将代码转换成汇编代码,然后使用汇编器再转换成二进制代码。使用这种编译很慢但是执行很快。但是使用编译器最大的问题是最后的机器代码是依赖于平台的。换句话说,运行在一台机器上的代码可能无法再另一台机器是运行。

3. Interpreters(解释器)

在执行的时候解释代码。由于解释发生在运行时,所以执行很慢。

JAVA 代码是如何执行的?

为了保持代码的平台独立性,JAVA 发明了 JVM(Java虚拟机)。它特别为每一个平台开发了 JVM,这就意味着 JVM 是依赖于平台的。Java 编译器将.java文件转化为.class文件,被称为字节码。JVM 会将字节码转为机器代码。

这比解释器要快,但是比 C++ 编译器慢。

Android 代码是如何执行的?

在 Android 中,Java 类被转化为 DEX 字节码,DEX 字节码通过 ART 或者 Dalvik 运行时转为了原生机器码。这里的 DEX 字节码是独立于设备架构的。

Dalvik 是一个基于 JIT(即时)的编译引擎。使用 Dalvik 是有缺点的,因此从 Android4.4(kitkat)开始引入了 ART 作为运行时,从 Android5.0(Lollopop)开始就完全替代了 Dalvik。Android7.0 增加了一个即时型编译器,给 Android 运行时(ART)提供了代码分析,提升了 Android app运行时的表现。

KEY POINT : Dalvik 使用 JIT(即时)编译,而 ART 使用 AOT(提前)编译。

下图说明了 Dalvik虚拟机和 Java虚拟机的区别:

JVM VS DVM

即时(JIT)

通过 Dalvik 即时编译器,每次app运行的时候,它动态的将一部分 Dalvik 字节码 解释为机器码。随着执行过程的进行,更多的字节码被编译和缓存。因此 JIT 只编译了一部分代码,它具有更小的内存占用和更少的设备物理空间占用。

提前(AOT)

ART 使用的是提前型编译器。在app的安装时期,它静态的将 DEX 字节码转化为机器码并存储在设备存储空间中。这是发生在安装过程中的一次性事件。由于不需要 JIT 编译,代码执行的更快了。

由于 ART 直接本地执行机器码,它不会像 Dalvik 一样频繁的访问 Cpu,更少的 Cpu 使用也降低了电量消耗。

dalvik_vs_art

ART 和 Dalvik 使用同样的字节码输入。一个使用 ART 编译的程序需要额外的时间在应用安装时进行编译,并且占据更大的空间来存储编译后的代码。

为什么 Android 使用虚拟机?

Android使用虚拟机作为运行时环境是为了运行 APK 文件,下面列举了好处:

ART 的好处

ART 的坏处

结论

ART 是为了在低内存设备上通过执行 DEX 文件(一种特别为安卓设计的优化过的,内存占用最小的字节码形式)可以运行多个虚拟机。关于 Dalvik 和 ART 的更多细节可以参照 official Android document

有任何疑问,欢迎加群讨论:261386924

Table of Contents