前阵子面试一个公司,自我介绍的时候说到自己曾经玩过Android但是现在做后台。然后面试官问我,那你知道Android的虚拟机和Java的虚拟机有什么区别吗?当时我就蒙蔽了,JVM了解过一些,知道JVM细分还是可以分好几种的,但是却不记得了,支支吾吾半天没答上来。于是回来便打算探讨一下这个问题。一查,才知道,原来Android的虚拟机都已不是JVM了,就算自己当时记得估计答的也是错的。Android的虚拟机叫做DVM。Dalvik Virtual Machine 是Android平台的基础。
Dalvik和标准Java虚拟机(JVM)之间的首要差别之一,就是Dalvik基于寄存器,而JVM基于栈。选择基于寄存器的方式是因为它对提前优化(ahead-of-time optimization)提供了更好的支持,而这对类似于移动电话这样的受限环境是颇有裨益的。另一份针对基于寄存器虚拟机和基于栈虚拟机更深入的比较分析指出,基于寄存器的虚拟机对于更大的程序来说,在它们编译的时候,花费的时间更短。
Dalvik和Java之间的另外一大区别就是运行环境——Dalvik经过优化,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个 Dalvik应用作为一个独立的Linux进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。(题外话:说句不专业的,再怎么优化感觉也是半斤八两,Android系统的用户体验确实不咋地)。
看了一些资料,这里来罗列(总结)一下这些区别吧:
1. DVM是Dalvik Virtual Machine的缩写,是安卓虚拟机的缩写(为什么不叫AVM-Android Virtual Machine呢?原因是其作者以其祖上居住过的名为Dalvik的村子命名)。
2. DVM是针对JVM(Java Virtual Machine)而言的,因为JVM是Oracle公司(原SUN公司)的产品,担心版权的问题,既然Java是开源的,索性就研究了JVM,写出了DVM
3. JVM和DVM的主要区别如下:
a) 执行的直接码文件不一样
Java:
.java文件 -> .class文件-> .jar文件
Android:
.java文件 –> .class文件 -> .dex文件
如上图所示,.jar文件里面包含多个.class文件,每个.class文件里面包含了该类的头信息(如编译版本)、常量池、类信息、域、方法、属性等等,当JVM加载该.jar文件的时候,会加载里面的所有的.class文件,这样会很慢,而移动设备的内存本来就很小,不可能像JVM这样加载,所以它使用的不是.jar文件,而是.apk文件,该文件里面只包含了一个.dex文件,这个.dex文件里面将所有的.class里面所包含的信息全部整合在一起了,这样再加载就很快了。.class文件存在很多的冗余信息,dex工具会去除冗余信息,并把所有的.class文件整合到.dex文件中。减少了I/O操作,提高了类的查找速度。
b) 基于的架构不一样
Java基于栈的架构.栈是内存上面的一段连续的存储空间
Android基于寄存器的架构.寄存器是CPU上面的一块存储空间
所以,CPU直接访问自己上面的一块空间的数据的效率肯定要大于访问内存上面的数据