- 深入解析Android 虚拟机
- 钟世礼
- 1437字
- 2020-06-28 05:36:03
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的初始化流程