Dalvik 虚拟机和 Sun JVM 在架构和执行方面的本质区别_第1页
Dalvik 虚拟机和 Sun JVM 在架构和执行方面的本质区别_第2页
Dalvik 虚拟机和 Sun JVM 在架构和执行方面的本质区别_第3页
Dalvik 虚拟机和 Sun JVM 在架构和执行方面的本质区别_第4页
Dalvik 虚拟机和 Sun JVM 在架构和执行方面的本质区别_第5页
已阅读5页,还剩1页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Dalvik虚拟机和SunJVM在架构和执行方面的本质区别Dalvik虚拟机和SunJVM核心的差异,就是Dalvik虚拟机架构是register-based,与SunJDK的stack-based不同,也就是架构上的差异。我先摘录几段网上可以找到的资料,重新整理和排版了一下,由于这些资料在网上经过多次转载,转发和加工,原作者不详,所以无法标注其原作者们,如有原作者认领或者质疑,请及时通知我。DalvikVM和JVM的第一个区别是DalvikVM是基于寄存器的架构(regbased),而JVM是栈机(stackbased)0regbasedVM的好处是可以做到更好的提前优化(ahead-of-timeoptimization)。另外regbased的VM执行起来更快,但是代价是更大的代码长度。另外一个区别是Dalvik可以允许多个instance运行,也就是说每一个Android的App是独立跑在一个VM中.这样做的好处是一个Appcrash只会影响到自身的VM,不会影响到其他。Dalvik的设计是每一个Dalvik的VM都是Linux下面的一个进程。那么这就需要高效的IPCo另外每一个VM是单独运行的好处还有可以动态active/deactive自己的VM而不会影响到其他VM接下来就是关于版权之类争论。(可以参看下面文章)既然regbasedVM有那么多好处,为什么之前设计JAVA的人没有采用regbased而是采用stackbased的呢?原来stackbased的VM也有其优点,就是它不对host平台的reg数量做假设,有利于移植到不同的平台。而Dalvik则不关心这些,因为它本来就是为ARM这样的多reg平台设计的。另外Dalvik被移植到x86也说明,即使是x86这种reg很少的平台,regbased的VM也是没有问题的。下面着重说下DVM的优势:(部分文字我加黑以突出)1、 在编译时提前优化代码而不是等到运行时2、 虚拟机很小,使用的空间也小;被设计来满足可高效运行多种虚拟机实例。3、 常量池已被修改为只使用32位的索引,以简化解释器JVM的字节码主要是零地址形式的,概念上说JVM是基于栈的架构。GoogleAndroid平台上的应用程序的主要开发语言是Java,通过其中的DalvikVM来运行Java程序。为了能正确实现语义,DalvikVM的许多设计都考虑到与JVM的兼容性;但它却采用了基于寄存器的架构,其字节码主要是二地址/三地址的混合形式。

基于栈与基于寄存器的架构,谁更快?现在实际的处理器,大多都是基于寄存器的架构,从侧面反映出基于寄存器比基于栈的架构更与实际的处理器接近。但对于VM来说,源架构的求值栈或者寄存器都可能是用实际机器的内存来模拟的,所以性能特性与实际硬件又有不同。一般认为基于寄存器架构的DalvikVM比基于栈架构JVM执行效率更高,原因是:虽然零地址指令更紧凑,但完成操作需要更多的load/store指令,也意味着更多的指令分派(instructiondispatch)次数与内存访问次数;访问内存是执行速度的一个重要瓶颈,二地址或三地址指令虽然每条指令占的空间较多,但总体来说可以用更少的指令完成操作,指令分派与内存访问次数都较少。我们从下面的截图可以明了的看到与同一段Java代码对应的Javabytecode与Dalvidbytecode的比较:Daluikbytecode代码Java1.0:Daluikbytecode代码Java1.0:iconst_lL1;3.2:iconst^Z4.3:istore_l5.4:iload06.s:iload^l7.6;8.7:9.8;imul1G.9:11.10:returnpublic jtl[:voicffoo()(tpn-5-t/41//盟R601:corus.t/4vltttint2H#2舶址;adcN"irrt/2ad.drV©jY13603:mul-int/lits7%#int5/海5:return-void5.gvik字节明以16位为单元[或许叫”双字节码'更淮确)-上面代码中有S条指令gvik字节明以16位为单元[或许叫”双字节码'更淮确)-上面代码中有S条指令,其中muH顽潮指令占2单元.其余每案都只占1单元’共6单元=12字节,5-arso££>HS,t/JLomst/flidd-iint/2dddirv(?p*1iulint/lit8v0|yB|flint5return^void,00()找零丫节码e@4icor^tI13Sistore01esiccxsst2KiGtore_l41AHcude5i]asd_l6l^dd7iconst5iwl930istcire1A◎序H«lJM■土”D1?t:讷11»】洒11131t6&163DAB0Java字节码以1字节为单元,上面代她有11条指令.莓条都只占1熊元,共”盈元字节网上一些文章在讨论Dalvik时,大都简单提及Dalvik执行速度比JVM快,但移植性稍差。这里我们延伸探讨一下。在一个解释器上执行VM指令,包含三个步骤,指令分派、访问操作数和执行计算。指令分派(Instructionsdispatch)负责从内存中读取VM指令,然后跳转到相应的解释器代码指令分派中。上面提到过,完成同样的事情,基于栈的虚拟机需要更多的指令,意味着更多的指令分派和内存访问次数,这是JVM的执行性能不如DalvikVM的原因之一。访问操作数访问操作数(Operandsaccess)是指读取和写回源操作数和目的操作数。DalvikVM通过虚拟操作数寄存器来访问操作数,由于具有相近的血缘,Dalvik的虚拟寄存器在映射到物理寄存器方面具有更充分的优势,这也是DalvikVM性能较佳的一个原因。JVM的操作数通过操作数栈来访问,而因为指令中没有使用任何通用寄存器,在虚拟机的实现中可以比较自由的分配实际机器的寄存器,因而可移植性高。作为一个优化,操作数栈也可以由编译器映射到物理寄存器上,减少数据移动的开销。指令执行(Instructionscompute)这个似乎没什么可解释的,老老实实执行就行。指令执行一个应用中会定义很多类,编译完成后即会有很多相应的CLASS文件,CLASS文件间会有不少冗余的信息。dex字节码和标准Java的字节码(Class)在结构上的一个区别是dex字节码将多个文件整合成一个,这样,除了减少整体的文件尺寸,I/O操作,也提高了类的查找速度。原来每个类文件中的常量池现在由DEX文件中一个常量池来管理。DEX文件可以进行进一步优化。优化主要是针对以下几个方面:1、调整所有字段的字节序(LITTLE_ENDIAN)和对齐结构中的没一个域2、 验证DEX文件中的所有类3、 对一些特定的类进行优化,对方法里的操作码进行优化优化优化后的文件大小会有所增加,应该是原DEX文件的1-4倍。odex是为了在运行过程中进一步提高性能,对dex文件的进一步优化每一个Android应用都运行在一个Dalvik虚拟机实例里,而每一个虚拟机实例都是一个独立的进程空间。每个进程之间可以通信(IPC,Binder机制实现)。虚拟机的线程机制,内存分配和管理,Mutex等等都是依赖底层操作系统而实现的。不同的应用在不同的进程空间里运行,当一个虚拟机关闭或意外中止时不会对其它虚拟机造成影响,可以最大程度的保护应用的安全和独立运行。Zygote是虚拟机实例的孵化器。AndroidRuntime.cpp中ZygoteInit.main()的执行会完成一个分裂,分裂出来的子进程继续初始化Java层的架构,这个分裂出来的进程就是system_server。每当系统要求执行一个Android应用程序,Zygote就会FORK出一个子进程来执行该应用程序。这样做的好处显而易见:Zygote进程是在系统启动时产生的,它会完成虚拟机的初始化,库的加载,预置类库的加载和初始化等等操作,而在系统需要一个新的虚拟机实例时,Zygote通过复制自身,最快速的提供个系统。另外,对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域,大大节省了内存开销。应用/虚拟机实例,进程虚拟机实例孵化器mb伽妍曲Horns^mraupCJ^Jnofneg他(irmapowil|x〃a陷<1中.1fpdw^leArty|0应用/虚拟机实例,进程虚拟机实例孵化器mb伽妍曲Horns^mraupCJ^Jnofneg他(irmapowil|x〃a陷<1中.1fpdw^leArty|0心阳山的I&TCMI44Tkv»odei&rdh«耶Islwiwldvf-y,rcMhomihWapsi眇恤好pTua.r4<3IWom"i"顷守gn蛔hrcvnZ-Jfldtfflflua/edHomZygofctHani«Isccd4WPY'Ewrgirir.炉vstC岳nJ============================二分割线===========================下面我简单总结描述一下,DVM和JVM这种架构上的差异所产生的影响JVM其核心目的,是为了构建一个真正跨OS平台,跨指令集的程序运行环境(VM)0DVM的目的是为了将androidOS的本地资源和环境,以一种统一的界面提供给应用程序开发。严格来说,DVM不是真正的VM,它只是开发的时候提供了VM的环境,并不是在运行的时候提供真正的VM容器。这也是为什么JVM必须设计成stack-based的原因。JVM:所有的jar程序,其运行环境完全是由JVM来提供,包括运行时,各类资源的调度,而JVM的架构,其设计为一个JVM里面可以运行多个java程序,JVM就像一个真正的“机器”,可以跑着多个程序。如果去看看一些企业级的JVM(例如tomcat,WAS),从OS的进程管理中,一般你只能看见一个JVM的进程(当然,你也可以起多个JVM,但JVM架构就是OS-JVM-APP的3层运行时模式),而看不见JVM里面运行的程序,而一个JVM里,可以跑多个javaapp。简单得说,JVM完全屏蔽了应用程序和OS之间的联系,而改用JVM充当了中间层,这也是一个真正跨平台运行时VM必须要做到的。只要是相同的JDK,JVM为所有在其中运行的程序,提供了完全一致的运行环境,而不论你是什么样的底层OS和硬件条件。因此这也是我在其他一篇答案中提到,JVM的特点是取底层OS和硬件环境的交集,从而保障这种一致性。而所有应用程序和底层资源的互动,一定是依赖JVM的传递和转换来实现。JVM真正实现了一个OS对应用程序运行时管理的所有功能。从开发环境角度和运行时角度,都是完全一致的真正VMDVM:而DVM的特点在于使用了Zygote,Zygote有几个非常有意思的特点。一是Zygote采用预加载,由其首先判定安装的APK的需要以及相互依存树,以及OS及硬件环境的特点,在每次启动的时候进行预加载(现在你明白为什么android的app在应用管理里你能轻易查到它都调用了那些重庆肛肠科关键性的本地资源的原因了吧?),这就意味着,你安装的应用越多,Zygote的加载就越慢,一般来说你的手机启动就会越慢。另外来说,在不同的硬件环境里(例如有无GPS芯片)Zygote初始化的实例是不同的。也就是说,zygote并不提供一个统一的运行环境,具有更好的弹性,这种机制意味着DVM可以取底层资源的合集来提供上层应用使用,差别只是在程序安装或者启动的过程中,DVM可以提示程序需求资源,本地环境可能未能满足而导致无法运行。DVM的Zygote并不是提供一个运行时容器,它提供的只是一个用于共享的进程,所有的应用程序运行,都是独立的,OS级别的进程,直接受到OS层面的资源控制以及调度的影响,只是他们共享Zygote说预加载的类而已。这也就是我为什么说,DVM就像是给每个应用程序在底层加了个套子,而不是提供了一个真正的运行时的VM。也就是说,DVM在开发环境中说提供的VM平台,和运行时的环境是很有可能不一致的。开发环境中提供的VM平台,是一个各种运行时可能环境的合集。从这点上来说,一般我们认为,JVM中的JAVA程序的崩溃,最多导致JVM的崩溃,而不会导致OS崩溃,但是apk的崩溃,可以直接导致OS崩溃,android手机会因为应用程序死机,大家应该是很常见了。但是大家一般是不会看到java程序导致死机吧?因为运行时中间隔着一个JVM。(当然,其实还是有些小门道可以用java程序让OS崩溃,因为这个,我和某些JAVA大拿打赌赢过饭局,呵呵,不过这是其他话题,不在这里展开了)除此之外,在JVM的机制中,不同的程序,打包以后,他们都是在运行层级真正独立的程序(指程序应用

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论