JVM
JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。用于运行由编译器(javac)编译而来的.class字节码文件。JVM数据模型是以栈为基础的。
JVM是实现跨平台的关键技术,跨平台的含义就是一次编译,到处运行,如何理解这句话?
请看下图:
上图是官网的不同JDK的下载,可以看出,虽然Java语言是跨平台的,编译器也是跨平台的,但是JDK却不是跨平台的,在将Java代码编译成字节码之后,该字节码的内容在不同机器上是一模一样的,但是不同机器上的JDK(主要是里面的JVM)会将字节码解释为平台相关的机器码。因此,跨平台并不是绝对的,只是不同的平台有不同的JDK可以用,而用户无需关注这种平台的差异罢了。
DVM
Dalvik VM是谷歌开发的安卓系统底层使用的虚拟机,用于运行由编译器编译而来的.dex字节码文件。从应用的层面看,每个app都对应一个系统进程与虚拟机实例,所以可以同时开启多个DVM实例。从架构的角度看,DVM使用的是寄存器模型。因为DVM的寄存器模型对硬件的利用程度很高,对于内存和CPU的占有率也不大,因此很适合于架构为ARM、MIPS以及x86的智能移动设备。
而SDK在用dx工具转化大部分.class文件为.dex文件的过程中,会将.class中冗余的内容比如空格、共享变量等去除,并把多个.class文件合并为一个.dex文件,因此.dex文件要小巧的多。
JVM PK DVM
Dalvik虚拟机和JVM不兼容!因为Dalvik根本就没有实现jvm的规范,导致了各种各样的区别:
1)JVM基于栈,而Dalvik基于寄存器;因为栈的操作相比寄存器而言要慢的多,所要调用的指令也更多,因此Dalvik要比JVM快的多,也方便对硬件能力的最大化使用,在移动设备方面(ARM系统)Dalvik显得很有优势。而JVM基于栈的好处是可以做的足够简单,真正的跨平台,确保在硬件不是很优化的情况下仍能正常运行。
2)JVM运行的是.class字节码,而Dalvik运行的是.dex字节码(.class文件通过一个叫dx的工具转化而来)。
3)Dalvik很小,使用的内存空间和CPU资源也小,这点也很适合移动设备。
4)回收机制方面,JVM会在每个对象的编码头部附加标记方便回收,而Dalvik会在GC前额外申请一块内存空间来保存对象的GC标记,然后用标记-清除算法来进行垃圾回收。
5)适用平台上,JVM可以跨平台使用,而DVM只适用于安卓设备。
6)执行包方面,JVM执行的是Jar包,DVM执行的是APK包(application package)。
7)JVM每个类都会开辟一个专有的常量池,而DVM是整个应用共享一个常量池。
8)DVM无版权限制(遵从Apache 2 license),而每种JVM或多或少都有。这也是为什么谷歌要用DVM而不是JVM的原因之一。
共同点:
1)都实现了JIT(Just In Time,即时编译)对于热代码(使用频率高的字节码)直接转换成汇编代码。
2)都用于运行字节码文件
ART
ART是DVM的进化版本,与DVM很大的不同之处在于ART可以直接运行机器码。前面说到,Dalvik运行的是.dex字节码文件,对于每个app安装的时候编译器都会加载编译APK包得到.dex文件,以后打开app的时候Dalvik就能直接运行字节码文件,但是还需要在运行的时候把字节码文件解释为机器码,如果能直接跳过字节码,直接运行机器码,将能大大提高应用的启动和运行速度。ART就是为此所做的改进,它会在APK编译的时候顺便把.dex文件编译成机器码,以后要用的时候直接运行就可以了。