dalvik虚拟机遵循的开源协议gpl.docx
- 文档编号:23171738
- 上传时间:2023-05-15
- 格式:DOCX
- 页数:13
- 大小:24.58KB
dalvik虚拟机遵循的开源协议gpl.docx
《dalvik虚拟机遵循的开源协议gpl.docx》由会员分享,可在线阅读,更多相关《dalvik虚拟机遵循的开源协议gpl.docx(13页珍藏版)》请在冰豆网上搜索。
dalvik虚拟机遵循的开源协议gpl
竭诚为您提供优质文档/双击可除
dalvik虚拟机遵循的开源协议?
gpl
篇一:
dalvik虚拟机和sunjVm在架构和执行方面的本质区别
dalvik虚拟机和sunjVm在架构和执行方
面的本质区别
dalvik虚拟机和sunjVm核心的差异,就是dalvik虚拟机架构是register-based,与sunjdk的stack-based不同,也就是架构上的差异。
我先摘录几段网上可以找到的资料,重新整理和排版了一下,由于这些资料在网上经过多次转载,转发和加工,原作者不详,所以无法标注其原作者们,如有原作者认领或者质疑,请及时通知我。
(1)dalvikVm和jVm的第一个区别是dalvikVm是基于寄存器的架构(regbased),而jVm是栈机(stackbased)。
regbasedVm的好处是可以做到更好的提前优化
(ahead-of-timeoptimization)。
另外regbased的Vm执行起来更快,但是代价是更大的代码长度。
(2)另外一个区别是dalvik可以允许多个instance运行,也就是说每一个android的app是独立跑在一个Vm中.这样做的好处是一个appcrash只会影响到自身的Vm,不会影响到其他。
dalvik的设计是每一个dalvik的Vm都是linux下面的一个进程。
那么这就需要高效的ipc。
另外每一个Vm是单独运行的好处还有可以动态active/deactive自己的Vm而不会影响到其他Vm
(3)接下来就是关于版权之类争论。
(可以参看下面文章)
既然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的比较:
网上一些文章在讨论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等等都是依赖底层操作系统而实现的。
不同的应用在不(dalvik虚拟机遵循的开源协议gpl)同的进程空间里运行,当一个虚拟机关闭或意外中止时不会对其它虚拟机造成影响,可以最大程度的保护应用的安全和独立运行。
zygote是虚拟机实例的孵化器。
androidRuntime.cpp中zygoteinit.main()的执行会完成一个分裂,分裂出来的子进程继续初始化java层的架构,这个分裂出来的进程就是system_server。
每当系统要求执行一个android应用程序,zygote就会FoRk出一个子进程来执行该应用程序。
这样做的好处显而易见:
zygote进程是在系统启动时产生的,它会完成虚拟机的初始化,库的加载,预置类库的加载和初始化等等操作,而在系统需要一个新的虚拟机实例时,zygote通过复制自身,最快速的提供个系统。
另外,对于一些只读的系统库,所有虚拟机实例都和zygote共享一块内存区域,大大节省了内存开销。
=============================分割线===========================
下面我简单总结描述一下,dVm和jVm这种架构上的差异所产生的影响
jVm其核心目的,是为了构建一个真正跨os平台,跨指令集的程序运行环境(Vm)。
dVm的目的是为了将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对应用程序运行时管理的所有功能。
从开发环境角度和运行时角度,都是完全一致的真正Vm
dVm:
而dVm的特点在于使用了zygote,zygote有几个非常有意思的特点。
一是zygote采用预加载,由其首先判定安装的apk的需要以及相互依存树,以及os及硬件环境的特点,在每次启动的时候进行预加载(现在你明白为什么android的app在应用管理里你能轻易查到它都调用了那些重庆肛肠科关键性的本地资源的原因了吧),这就意味着,你安装的应用越多,zygote
的加载就越慢,一般来说你的手机启动就会越慢。
另外
篇二:
android无缝替换dalvik虚拟机
androidaRt运行时无缝替换dalvik虚拟机的过程分析我们知道,dalvik虚拟机实则也算是一个java虚拟机,只不过它执行的不是class文件,而是dex文件。
因此,aRt运行时最理想的方式也是实现为一个java虚拟机的形式,这样就可以很容易地将dalvik虚拟机替换掉。
注意,我们这里说实现为java虚拟机的形式,实际上是指提供一套完全与java虚拟机兼容的接口。
例如,dalvik虚拟机在接口上与java虚拟机是一致的,但是它的内部可以是完全不一样的东西。
实际上,aRt运行时就是真的和dalvik虚拟机一样,实现了一套完全兼容java虚拟机的接口。
为了方便描述,接下来我们就将aRt运行时称为aRt虚拟机,它和dalvik虚拟机、java虚拟机的关系如图1所示:
图1java虚拟机、dalvik虚拟机和aRt运行时的关系
从图1可以知道,dalvik虚拟机和aRt虚拟机都实现了三个用来抽象java虚拟机的接口:
1.jni_getdefaultjavaVminitargs--获取虚拟机的默认初始化参数
2.jni_createjavaVm--在进程中创建虚拟机实例
3.jni_getcreatedjavaVms--获取进程中创建的虚拟机实例
在android系统中,davik虚拟机实现在libdvm.so中,aRt虚拟机实现在libart.so中。
也就是说,libdvm.so和libart.so导出了jni_getdefaultjavaVminitargs、
jni_createjavaVm和jni_getcreatedjavaVms这三个接口,供外界调用。
此外,android系统还提供了一个系统属性persist.sys.dalvik.vm.lib,它的值要么等于libdvm.so,要么等于libart.so。
当等于libdvm.so时,就表示当前用的是dalvik虚拟机,而当等于libart.so时,就表示当前用的是aRt虚拟机。
以上描述的dalvik虚拟机和aRt虚拟机的共同之处,当然它们之间最显著还是不同之处。
不同的地方就在于,dalvik虚拟机执行的是dex字节码,aRt虚拟机执行的是本地机器码。
这意味着dalvik虚拟机包含有一个解释器,用来执行dex字节码,具体可以参考dalvik虚拟机简要介绍和学习计划这个系列的文章。
当然,android从2.2开始,也包含有jit(just-in-time),用来在运行时动态地将执行频率很高的dex字节码翻译成本地机器码,然后再执行。
通过jit,就可以有效地提高dalvik虚拟机的执行效率。
但是,将dex字节码翻译成本地机器码是发生在应用程序的运行过程中的,并且应用程序每一次重新运行的时候,都要做重做这个翻译工作的。
因此,即使用采用了jit,dalvik虚拟机的总体性能还是不能与直接执行本地机器码的aRt虚拟机相比。
那么,aRt虚拟机执行的本地机器码是从哪里来的呢?
android的运行时从dalvik虚拟机替换成aRt虚拟机,并不要求开发者要将重新将自己的应用直接编译成目标机器码。
也就是说,开发者开发出的应用程序经过编译和打包之后,仍然是一个包含dex字节码的apk文件。
既然应用程序包含的仍然是dex字节码,而aRt虚拟机需要的是本地机器码,这就必然要有一个翻译的过程。
这个翻译的过程当然不能发生应用程序运行的时候,否则的话就和dalvik虚拟机的jit一样了。
在计算机的世界里,与jit相对的是aot。
aot进ahead-of-time的简称,它发生在程序运行之前。
我们用静态语言(例如c/c++)来开发应用程序的时候,编译器直接就把它们翻译成目标机器码。
这种静态语言的编译方式也是aot的一种。
但是前面我们提到,aRt虚拟机并不要求开发者将自己的应用直接编译成目标机器码。
这样,将应用的dex字节码翻译成本地机器码的最恰当aot时机就发生在应用安装的时候。
我们知道,没有aRt虚拟机之前,应用在安装的过程,其实也会执行一次“翻译”的过程。
只不过这个“翻译”的过程是将dex字节码进行优化,也就是由dex文件生成odex文件。
这个过程由安装服务packagemanagerservice请求守护进程installd来执行的。
从这个角
度来说,在应用安装的过程中将dex字节码翻译成本地机器码对原来的应用安装流程基本上就不会产生什么影响。
有了以上的背景知识之后,我们接下来就从两个角度来了解aRt虚拟机是如何做到无缝替换dalvik虚拟机的:
1.aRt虚拟机的启动过程;
2.dex字节码翻译成本地机器码的过程。
我们知道,android系统在启动的时候,会创建一个zygote进程,充当应用程序进程孵化器。
zygote进程在启动的过程中,又会创建一个dalvik虚拟机。
zygote进程是通过复制自己来创建新的应用程序进程的。
这意味着zygote进程会将自己的dalvik虚拟机复制给应用程序进程。
通过这种方式就可以大大地提高应用程序的启动速度,因为这种方式避免了每一个应用程序进程在启动的时候都要去创建一个dalvik。
事实上,zygote进程通过自我复制的方式来创建应用程序进程,省去的不仅仅是应用程序进程创建dalvik虚拟机的时间,还能省去应用程序进程加载各种系统库和系统资源的时间,因为它们在zygote进程中已经加载过了,并且也会连同dalvik虚拟机一起复制到应用程序进程中去。
关于zygote进程和应用程序进程启动的更多知识,可以参考android系统进程zygote启动过程的源代码分析和android应用程序进程启动过程的源代码分析这两篇文章。
即然应用程序进程里面的dalvik虚拟机都是从zygote进程中复制过来的,那么接下来我们就继续zygote进程是如何创建dalvik虚拟机的。
从dalvik虚拟机的启动过程分析这篇文章可以知道,zygote进程中的dalvik虚拟机是从androidRutime:
:
start这个函数开始创建的。
因此,接下来我们就看看这个函数的实现:
[cpp]viewplaincopy
1.voidandroidRuntime:
:
start(constchar*classname,constchar*options)
2.{
3.......
4.
5./*startthevirtualmachine*/
6.jniinvocationjni_invocation;
7.jni_invocation.init(null);
8.jnienv*env;
9.if(startVm(
11.}
12.
13.......
14.
15./*
16.*startVm.thisthreadbecomesthemainthreadoftheVm,andwill
17.*notreturnuntiltheVmexits.
18.*/
19.char*slashclassname=toslashclassname(classname);
20.jclassstartclass=env->Findclass(slashclassname);
21.if(startclass==null){
22.aloge("javaVmunabletolocateclass%s\n",slashclassname);
23./*keepgoing*/
24.}else{
25.jmethodidstartmeth=env->getstaticmethodid(startclass,"main",
26."([ljava/lang/string;)V");
27.if(startmeth==null){
28.aloge("javaVmunabletofindmain()in%s\n",classname);
29./*keepgoing*/
30.}else{
31.env->callstaticVoidmethod(startclass,startmeth,strarray);32.
33.#if0
34.if(env->exceptioncheck())
35.threadexituncaughtexception(env);
36.#endif
37.}
38.}
39.
40.......
41.}
这个函数定义在文件frameworks/base/core/jni/androidRuntime.cpp中。
androidRutime类的成员函数start最主要是做了以下三件事情:
1.创建一个jniinvocation实例,并且调用它的成员函数init来初始化jni环境;
2.调用androidRutime类的成员函数startVm来创建一个虚拟机及其对应的jni接口,即创建一个javaVm接口和一个jnienv接口;
3.有了上述的javaVm接口和jnienv接口之后,就可以在zygote进程中加载指定的class了。
其中,第1件事情和第2件事情又是最关键的。
因此,接下来我们继续分析它们所对应的函数的实现。
jniinvocation类的成员函数init的实现如下所示:
[cpp]viewplaincopy1.#ifdefhaVe_andRoid_os
2.staticconstchar*klibrarysystemproperty="persist.sys.dalvik.vm.lib";
3.#endif
4.staticconstchar*klibraryFallback="libdvm.so";
5.
6.booljniinvocation:
:
init(constchar*library){
7.#ifdefhaVe_andRoid_os
8.chardefault_library[pRopeRty_Value_max];
9.property_get(klibrarysystemproperty,default_library,klibraryFallback);
10.#else
11.constchar*default_library=klibraryFallback;
12.#endif
13.if(library==null){
14.library=default_library;
15.}
16.
17.handle_=dlopen(library,Rtld_now);
18.if(handle_==null){
19.if(strcmp(library,klibraryFallback)==0){
20.//nothingelsetotry.
21.aloge("Failedtodlopen%s:
%s",library,dlerror());
22.returnfalse;
23.}
24.//notethatthisisenoughtogetsomethinglikethezygote
25.//running,wecantproperty_setheretofixthisforthefuture
26.//becausewearerootandnotthesystemuser.see
27.//Rmoninitforwherewefixupthepropertyto
28.//avoidfuturefallbacks.http:
//b/11463182
29.alogw("Fallingbackfrom%sto%safterdlopenerror:
%s",
30.library,klibraryFallback,dlerror());
31.library=klibraryFallback;
32.handle_=dlopen(library,Rtld_now);
33.if(handle_==null){
34.aloge("Failedtodlopen%s:
%s",library,dlerror());
35.returnfalse;
36.}
37.}
篇三:
dalvik虚拟机jit架构移植调研报告
jit调研报告
目录
jit调用报告.....................................................................................................................1
jit简介.....................................................................................................................2
汇编代码部分............................................................................................................4
c代码部分................................................................................................................4
compiler目录下文件略析..........................................................................................5
intermediateRep.c.........................................
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- dalvik 虚拟机 遵循 协议 gpl
![提示](https://static.bdocx.com/images/bang_tan.gif)