3.3 Dalvik VM架构

在Android源码中,Dalvik虚拟机的实现位于“dalvik/”目录下,其中“dalvik/vm”是虚拟机的实现部分,将会编译成libdvm.so。而“dalvik/libdex”将会编译成libdex.a静态库,作为dex工具使用;“dalvik/dexdump”是.dex文件的反编译工具,虚拟机的可执行程序位于“dalvik/dalvikvm”中,将会编译成dalvikvm可执行文件。

Dalvik虚拟机的架构如图3-1所示。

图3-1 Dalvik虚拟机的架构

Android应用编译及运行流程如图3-2所示。

图3-2 Android应用编译及运行流程

3.3.1 Dalvik虚拟机的代码结构

Dalvik是Android程序的Java虚拟机,代码保存在“dalvik/”目录下,目录的具体结构如下所示:

        ./
        |-- Android.mk
        |-- CleanSpec.mk
        |-- MODULE_LICENSE_APACHE2
        |-- NOTICE
        |-- README.txt
        |--dalvikvm虚拟机的实现库
        |-- dexdump
        |-- dexlist
        |-- dexopt
        |-- docs
        |-- dvz
        |-- dx
        |-- hit
        |-- libcore
        |-- libcore-disabled
        |-- libdex
        |--libnativehelper使用JNI调用本地代码时用到这个库
        |-- run-core-tests.sh
        |-- tests
        |-- tools
        `-- vm

“dalvik/”目录的效果图如图3-3所示。

图3-3 “dalvik/”目录的效果图

Dalvik虚拟机各个目录的具体说明如下所示:

android.mk:是虚拟机编译的makefile文件。

dalvikvm:此目录是虚拟机命令行调用入口文件的目录,主要用来解释命令行参数,调用库函数接口等。

dexdump:此目录是生成dex文件反编译查看工具,主要用来查看编译出来的代码文件是否正确,查看编译出来的文件结构如何。

dexlist:此目录是生成查看dex文件里所有类的方法的工具。

dexopt:此目录是生成dex优化工具。

docs:此目录是保存Dalvik虚拟机相关帮助文档。

dvz:此目录是生成从Zygote请求生成虚拟机实例的工具。

dx:此目录是生成从Java字节码转换为Dalvik机器码的工具。

hit:此目录是生成显示堆栈信息/对象信息的工具。

libcore:此目录是Dalvik虚拟机的核心类库,提供给上层的应用程序调用。

libcore-disabled:此目录是一些禁用的库。

libdex:此目录是生成主机和设备处理DEX文件的库。

libnativehelper:此目录是Dalvik虚拟核心库的支持库函数。

MODULE_LICENSE_APACHE2:这个是APCHE2的版权声明文件。

NOTICE:这个文件是说明虚拟机源码的版权注意事项。

README.txt:这个文件是说明本目录相关内容和版权。

run-core-tests.sh:这个文件是用来运行核心库测试。

tests:此目录是保存测试相关测试用例。

tools:此目录是保存一些编译/运行相关的工具。

vm:此目录是保存虚拟机绝大部份代码,包括读取指令读取、指令执行等。

3.3.2 dx工具

在Android虚拟机中,dx工具是用来转换Java Class成为DEX格式,但不是全部。多个类型包含在一个DEX文件之中。多个类型中重复的字符串和其他常数包括会存放在DEX之中只有一次,以节省空间。Java字节码(betecode)转换成Dalvik虚拟机所使用的替代指令集。一个未压缩DEX文件通常是稍稍小于一个已经压缩.Jar文档。

当启动Android系统时,Dalvik VM监视所有的程序(APK),并且创建依存关系树,为每个程序优化代码并存储在Dalvik缓存中。Dalvik VM第一次加载后会生成Cache文件,以提供下次快速加载,所以第一次会变得很慢。

Dalvik VM解释器采用预先算好的Goto地址,基于每个指令集OpCode,都固定以64 B为Memory Alignment。这样可以节省一个指令集OpCode后,要进行查表的时间。为了强化功能,Dalvik VM还提供了Fast Interpreter。

dx是一套工具,可以将Java的.class文件转换成.dex格式。一个dex文档通常会有多个.class文件。由于dex有时必须进行优化,会使文件大小增加1~4倍,以ODEX结尾。

3.3.3 Dalvik VM的进程管理

Dalvik VM进程管理是依赖于Linux的进程体系结构的,如要为应用程序创建一个进程,它会使用Linux的fork机制来复制一个进程(复制进程往往比创建进程效率更高)。

Zygote是一个虚拟机进程,同时也是一个虚拟机实例的孵化器,它通过init进程启动。首先会孵化出System_Server(Android绝大多系统服务的守护进程,它会监听Socket等待请求命令,当有一个应用程序启动时,就会向它发出请求,Zygote就会FORK出一个新的应用程序进程)。每当系统要求执行一个Android应用程序时,Zygote就会运用Linux的FORK进制产生一个子进程来执行该应用程序。

3.3.4 Android的初始化流程

Linux中的进程间通信方式有很多,但是Dalvik VM是使用信号方式来完成进程间的通信工作的。Android的初始化流程如图3-4所示。

图3-4 Android的初始化流程