首页 > 代码库 > Dalvik VM和JVM的浅析
Dalvik VM和JVM的浅析
http://zh.wikipedia.org/wiki/Android
http://zh.wikipedia.org/wiki/Dalvik虚拟机
http://zh.wikipedia.org/wiki/Java虚拟机
一、Dalvik VM和JVM的理解
JVM是一个虚构出来的运行Java程序的运行时,是通过在实际的计算机上仿真模拟各种计算机功能的实现。它具有完善的硬件架构(如处理器,堆栈,寄存器等),还具有相应的指令系统,使用JVM就是使Java程序支持与操作系统无关。理论上在任何操作系统中,只要有对应的JVM,即可运行Java程序。
Dalvik VM是在Android系统上运行的Android程序虚拟机,其指令集是基于寄存器架构(Register-Based),执行特有的文件格式——dex字节码来完成对象生命周期管理、堆栈管理、线程管理、安全异常管理、垃圾回收等重要功能。
Android应用程序的开发编程语言是Java,运行在JVM上,但实际上,Dalvik并未遵守JVM规范,而且两者也是互不兼容的。
编译过程如下:
JVM: .java→.class→.jar
Dalvik VM: .java→.class→.dex (优化)→.odex
从Dalvik VM和JVM的编译过程来看,JVM运行的是.class文件的Java字节码,而Dalvik VM运行的是其转换后的.dex文件。Dalvik VM会对.class进行重构,整合的基本元素(常量池、类定义、数据段)最后压缩进一个.dex文件中。
JVM基于栈的架构,字节码主要是零地址形式。Dalvik VM基于寄存器架构,其字节码主要是二地址/三地址的混合形式。两种架构谁更快?对于VM来说,源架构的求值栈或者寄存器都可能是用实际机器的内存来模拟的,所以性能特性与实际硬件又有不同。一般认为,基于寄存器架构的Dalvik VM比基于栈架构的JVM执行效率更高(一般来说,VM中指令的解释执行的时间主要花费在 分发指令、访问运算数、执行运算 三个方面),虽然零地址指令更紧凑,但完成操作需要更多的load/store指令,也意味着更多的指令分派(instruction dispatch)次数与内存访问次数;访问内存是执行速度的一个重要瓶颈,二地址或者三地址虽然每条指令占的空间较多,但总体来说可以用更少的指令完成操作,指令分派与内存访问次数都较少。
.dex字节码和.class字节码在结构上的一个区别是.dex字节码将多个文件整合成一个,这样处理减少整体文件尺寸,I/O操作,也提高了类的查找速度,原来每个类文件中的常量池现在有dex文件中的一个常量池来管理。dex文件还可以进行进一步的优化:
1、调整所有字段的字节序(LITTLE_ENDIAN)和对齐结构中的每一个域
2、验证DEX文件中的所有类
3、对一些特定的类惊醒优化,对方法里的操作码进行优化
优化后的文件大小会有所增加,应该是原来DEX文件的1~4倍。
一个Android应用程序运行在一个Dalvik虚拟机实例里,而每一个虚拟机实例都是一个独立的进程空间。每个进程之间可以通行(IPC,Binder机制实现)。虚拟机线程机制,内存分配管理,Mutex等等都是在依赖底层操作系统而实现的。不同的应用在不同的进程空间里运行,当一个虚拟机关闭或者意外中止时不会对其他虚拟机造成影响,可以最大程度的保护应用的安全和独立运行。
Zygote是虚拟机实例的孵化器。AndroidRuntime.cpp中ZygoteInit.main()的执行会完成一个分裂,分裂出来的子进程继续初始化Java层的架构。每当系统要求执行一个Android应用程序,Zygote就会分裂出一个子进程来执行该程序。这样做的好处显而易见:Zygote进程是在系统启动时产生的,它会完成虚拟机的初始化,库的加载,预置类库的加载和初始化等等操作,而在系统需要一个新的虚拟机实例时,Zygote通过自身复制,最快速的提供这个系统,另外,对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域,大大节省了内存开销。
二、Dalvik VM和JVM区别小结
1、Dalvik基于寄存器(Register Based),JVM基于栈(Stack Based)。
2、JVM的核心目的是为了构建一个真正跨平台、跨指令集的程序运行环境,完全屏蔽了应用程序和OS之间的联系。DVM的目的是为了将Android OS的本地资环和环境,以统一的界面提供给应用程序开发。
3、JVM使用.class的字节码文件,而Dalvik VM使用专有的 .dex字节码文件
4、Dalvik允许在有限的内存中同时运行多个虚拟机的实例,并且每一个Dalvik 应用作为一个独立的Linux 进程执行。独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
5、Dalvik虚拟机早期并没有使用即时编译(JIT)技术。从 Android 2.2 开始,Dalvik 虚拟机也支持 JIT。
6、Dalvik VM 通过 Zygote 进行类的预加载,Zygote会完成虚拟机的初始化,也是与 JVM 不同之处。
ART简介:
ART模式是Android runtime的简称。在Android 4.2以前,安卓手机系统的应用程序均在Dalvik Java的虚拟机上运行,这种运行模式是还要依靠一个编译器来实现与应用程序的沟通。应程序每次运行时,都需要将程序内的代码即使转变为机器码才能运行,这就造成了耗电相对较快、占用内存大、即使是旗舰机用久了也会卡顿严重的现象。
ART模式和Dalvik模式,相比较而言ART模式就很好的解决了这个问题,通过在安装应用程序时,自动对程序进行代码预读取编译,让程序直接编译成机器语言,免去了Dalvik模式要时时转换代码,实现高效率、省电、占用更低的系统内存、手机运行流畅。但凡事总有正反两面,ART在解决了该问题的同时,同时也有如:会占用略高一些的存储空间、安装程序时要相比普通Dalvik模式要长一些时间来实现预编译。不过,谷歌表示这个差距不是很大,而且他们会在这方面努力改善,使其效率接近甚至超过Dalvik;另一个缺点是原生代码占用的存储空间更大,不过,对于现在手机和平板的存储空间来说这一点点多出来的容量需求不是什么问题。
参考资料:
http://www.zhihu.com/question/20207106/answer/14654536
http://book.51cto.com/art/201404/437195.htm
http://blog.csdn.net/x356982611/article/details/21983267
Dalvik VM和JVM的浅析