Dalvik VM (DVM) 与Java VM (JVM)之间的区别

前言

       DVM和JVM之间的区别应该算是Android面试的常客了,也是比较深入原理性的东西,今天花了点时间整理了一下,收获良多。

区别

        1、DVM和JVM最核心的区别是:DVM基于寄存器的架构,而JVM基于栈的架构。基于寄存器的好处是可以更好的做提前优化从而执行速度更快,但是代码长度更长,基于栈的好处是方便移植。
        2、另外一个区别是DVM允许存在多个实例运行,每一个Android App对应一个DVM,这样做的好处是,当一个App Crash之后,不会影响其他App。因此DVM需要更加高性能的IPC通信机制,如Binder。JVM的设计是在一个JVM中可以运行多个应用程序。

DVM的优势
        1.在编译时优化代码,而不是运行时;
        2.虚拟机很小,使用空间也很小,被设计用于满足多种虚拟机实例;
        3.常量池也被修改为使用32位索引,以简化解释器;

        JVM的字节码主要是零地址形式,概念上说JVM是基于栈的;DVM其字节码主要是二地址/三地址的混合形式。
        基于栈和基于寄存器的处理器谁更快?实际生活中的大多数处理器是基于寄存器的,从侧面反映出基于寄存器的处理器比基于栈的处理器更符合实际需求。一般认为基于寄存器的架构比基于栈的架构处理速度更快,原因是虽然零地址指令更紧凑,但完成操作需要更多的load/和store指令,也意味着更多的指令分发次数和内存访问次数;访问内存是执行速度的一个重要瓶颈,二地址/三地址虽然每条指令占用的空间较多,但总体来说可以更少的指令完成操作,指令分配和内存访问次数都较少,等于是空间换时间。

        我们从下面的截图可以明了的看到与同一段Java代码对应的Java bytecode 与Dalvid bytecode的比较:

image.png

image.png

        大多数文章都是简单提及DVM比JVM执行效率高但是移植性差,这里我们扩展一下,在一个解释器上执行VM指令,需要经历3个步骤,分别是:指令分发、访问操作数和执行计算。
        指令分发(Instructions dispatch)负责从内存中读取VM指令,然后跳转到相应的解释器代码。上面提到过,基于栈的虚拟机,需要更多的指令分发和内存访问次数。这是JVM执行性能不如DVM的原因之一。
        访问操作数(Operands access)是指读取和写会源操作数和目的操作数。DVM通过虚拟操作数寄存器来访问操作数,由于具有相近的血缘,DVM的虚拟寄存器映射到物理寄存器方面有先天优势,这也是DVM性能较佳的原因之一。JVM操作数通过操作数栈来访问,而因为指令中没有任何通用寄存器,在虚拟机的实现中可以比较自由分配实际机器的寄存器,因而可移植性高。
        指令执行(Instructions compute)没啥好解释的,好好执行就行了。

        一个应用中会定义很多类,通过JDK编译之后会变成class文件,class文件会有不少冗余信息。dex字节码和标准的java字节码(class)在结构上的一个区别是dex将多个文件整合成一个,这样,减少了整体的文件尺寸,I/O操作,也提高了查找速度。原来每个类文件中的常量池现在有dex文件中一个常量池来管理。
       dex文件可以进一步优化,优化方向主要针对以下几个方面:
       1、调整所有字段的字节序(LITTLE_ENDIAN)和对齐结构中的每一个域;
       2、验证dex文件中的所有类;
       3、对一些特定的类进行优化,对方法里的操作码进行优化。
优化后的文件会有所增加,一般来说是原dex文件的1-4倍。odex是为了运行时提高性能,对dex的进一步优化。
image.png

总结

        JVM的核心目的,是为了构建一个真正的跨OS平台,跨指令集的运行环境。DVM是为了将Android OS的本地资源和环境,以一种统一方式提供给应用程序开发。严格来说,DVM并不是真正的VM,他只是开发的时候提供了VM环境,并不是运行的时候提供VM容器。这也是JVM必须设计成基于栈(stack-based)的架构。
        JVM:所有的jar程序,其运行环境完全是由JVM来提供,包括运行时各类资源的调度,而JVM架构,其设计为一个JVM里运行多个JAVA程序,JVM就像一个真正的机器,可以运行多个程序。
        DVM:DVM的特点在于使用了Zygote。Zygote有几个特点:
一是Zygote采用预加载,由其首先判定安装的apk的需要以及依存树,以及OS和硬件环境的特点,在每次启动的时候进行预加载,这就意味着,你安装的应用越多,Zygote的加载越慢,相应的手机启动也就越慢。
二是不同的硬件环境Zygote的初始化实例是不一样的。也就是说Zygote并不提供统一的运行环境,具有更好的弹性,这种机制意味着DVM可以取底层资源的合集供上层应用程序使用,差别只是在程序安装和启动过程,DVM可以提示程序需求需求资源,本地环境可能无法满足而导致无法运行。
       Zygote并不是提供一个运行时容器,它提供的只是一个用于共享的进程,所有程序的运行都是独立的,都是OS级别的的进程,直接受到OS层面的资源调度影响,只是他们共享Zygote预加载类而已。这也就是为什么说,DVM就像是给每个应用程序在底层加了一个套子,而不是提供一个真正运行时的VM。

参考:
https://www.zhihu.com/question/20207106

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值