Java虚拟机运行的是Java字节码,Dalvik虚拟机运行的是Dalvik字节码
传统的Java程序经过编译,生成Java字节码,保存在class文件中,Java虚拟机通过解码class文件中的内容来运行程序。而Dalvik虚拟机运行的是Dalvik字节码,所有的Dalvik字节码由Java字节码转换而来,并被打包到一个DEX可执行文件中,Dalvik虚拟机通过解释DEX文件来执行这些字节码。
Dalvik可执行文件体积更小
一般情况下,Java类文件中包含多个不同的方法签名,如果其他的类文件引用该类文件中的方法,那么方法签名也会被复制到其类文件中,那么就会造成多个不同的类会同时包含相同的方法签名,同样的,大量的字符串常量在多个类文件中也被重复使用,这些冗余的信息会直接增加文件的体积,同时也会严重影响虚拟机解析文件的效率。
在Android SDK中有一个叫做dx的工具,它负责将Java字节码转换为Dalvik字节码。dx工具会对Java类文件重新排列,消除在类文件中出现的所有冗余信息,避免虚拟机在初始化时出现反复的文件加载和解析过程。dx工具会将所有的Java类文件中的常量池进行分解,消除其中的冗余信息,重新组合形成一个常量池,所有类文件共享一个常量池。
Java虚拟机与Dalvik虚拟机架构不同
Java虚拟机是基于栈架构。程序在运行时虚拟机需要频繁的从栈上读取或者写入数据,这个活动需要更多的指令分配与内存访问次数,会消耗不少CPU时间。
Dalvik虚拟机基于寄存器架构,数据的访问通过寄存器间直接传递,这样的访问方式比基于栈方式要快很多。
Dalvik虚拟机运行时为每个线程维护一个PC计数器与调用栈,这个调用栈维护一份寄存器列表,寄存器的数量在方法结构体的registers字段中给出,Dalvik虚拟机会根据这个值来创建一份虚拟的寄存器列表。