虚拟机

Android的虚拟机主要有两种:Dalvik 虚拟机 ART(Android Runtime)虚拟机

Dalvik 虚拟机 Dalvik 虚拟机是 Android 早期使用的虚拟机,它基于寄存器架构。从Android 2.2版本开始,支持JIT即时编译(Just In Time)在程序运行的过程中进行选择热点代码(经常执行的代码)进行编译或者优化。Dalvik 执行的是经过转换优化后的 dex(Dalvik Executable)字节码文件,而不是传统的 Java 字节码。Dalvik 虚拟机针对移动设备的特点进行了优化,具有较小的内存占用和较高的执行效率。每个应用程序都在独立的 Dalvik 虚拟机实例中运行,实现了应用程序之间的隔离。

ART 虚拟机 自 Android 5.0(Lollipop)起,Android 引入了 ART 虚拟机作为默认的运行环境。ART 使用 Ahead-Of-Time(AOT)编译技术,将 dex 字节码在应用安装时预先编译成本地机器码,这样在运行时就无需再进行实时的字节码转换,提高了应用程序的启动速度和执行效率。与 Dalvik 不同,ART 的执行方式更接近于传统的 Java 虚拟机,采用基于堆栈的指令集

区别

基于寄存器的虚拟机

在基于寄存器的虚拟机中,将数据保存在寄存器中。虚拟寄存器可以看作是一个数组,用于存储局部变量、参数和临时变量等运行时数据。每个虚拟寄存器都有自己的编号,可以通过编号来访问和操作寄存器中的值。

在 Dalvik VM 中,每个线程都有自己的程序计数器(Program Counter,PC)和调用栈。程序计数器用于记录当前线程执行到的指令位置,而调用栈则用于保存方法调用的活动记录,每个活动记录称为一个帧(frame)。每个帧包含了方法的局部变量表和操作数寄存器等信息。

因此,对于基于寄存器的虚拟机来说,数据存放在寄存器中,虚拟寄存器是一个数组,保存在运行时栈中。每个线程都有自己的程序计数器和调用栈,方法调用的活动记录以帧为单位保存在调用栈上。

基于栈的虚拟机

每个虚拟机运行时线程都有自己独立的栈。栈用来记录方法调用的历史,每当一个方法被调用时,就会在栈中创建一个新的栈帧(stack frame)。栈帧包含了方法的局部变量表、操作数栈以及一些额外的信息。

栈的顶部栈帧被称为当前栈帧,代表当前正在执行的方法。栈帧中的局部变量表用于存储方法中定义的局部变量和参数,而操作数栈用于执行方法中的操作。

基于栈的虚拟机通过操作数栈进行所有的指令操作。指令可以从操作数栈中取出操作数,执行相应的操作,然后将结果再次压入操作数栈中。这种基于栈的指令集设计简洁紧凑,并且不依赖于具体的硬件架构,因此能够实现较好的跨平台性。

方法执行完成或者遇到方法调用时,当前栈帧会被弹出,并且恢复到上一个栈帧,继续执行上一个方法。这样,通过不断创建和销毁栈帧,基于栈的虚拟机能够实现方法之间的无缝切换和控制流的管理。

总结起来,基于栈的虚拟机使用独立的栈来记录方法调用历史,每个栈帧代表一个方法的执行上下文,包含局部变量表和操作数栈。通过操作数栈进行指令操作,实现方法间的切换和控制流管理。这种设计具有简洁、紧凑和跨平台等特点。

Android程序安装优化

当一个应用在 Android 系统上被安装时,会根据所使用的运行时环境(Dalvik 或 ART)执行不同的优化过程。

Dalvik 虚拟机中,应用在安装过程中会进行一次优化,将应用的 dex 字节码转换为优化的可执行文件 odex(Optimized DEX)文件。这个优化过程由 dexopt 工具完成。dexopt 根据设备配置和系统策略,对 dex 文件进行字节码优化、预解析和预验证等操作,并生成 odex 文件。odex 文件包含了已经优化过的字节码以及相关的元数据信息,加速了应用运行时的加载和执行速度。

而在 ART(Android Runtime)中,引入了预先编译机制(Ahead Of Time Compilation)。在应用安装时,ART 使用设备自带的dex2oat工具将应用的 dex 字节码直接编译成本地机器码,也就是将应用的 dex 文件转换为 ELF(Executable and Linkable Format)可执行文件。这个编译过程可以发生在应用安装期间,也可以在应用首次运行时发生,具体取决于设备和系统策略。

通过将 dex 字节码编译为本地机器码,ART 提供了更高的应用执行性能和更低的内存占用。与 Dalvik 不同,ART 在应用运行时无需进行即时编译(Just-In-Time Compilation),而是直接执行本地机器码,提高了应用的响应速度和效率。

android虚拟机中查看数据库_android