Android开发之浅谈java虚拟机和Dalvik虚拟机的区别

来源:互联网 发布:普通电视怎么连接网络 编辑:程序博客网 时间:2024/04/30 11:52

Dalvik虚拟机 依赖于底层Posix兼容的操作系统,它可以简单的完成进程隔离和线程管理。它有着对内存的高效使用和在低速CPU上表现出的高性能。每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例, 其代码在虚拟机的解释下得以执行。Dalvik虚拟机并不是按照Java虚拟机的规范来实现的,与jvm并不兼容;同时还要两个明显的不同:

  • Java虚拟机运行的是Java字节码,而Dalvik虚拟机运行的则是其专有的文件格式DEX(Dalvik Executable)。
  • 在Java SE程序中的Java类会被编译成一个或者多个字节码文件(.class)然后打包到JAR文件,而后Java虚拟机会从相应的CLASS文件和JAR文 件中获取相应的字节码;Android应用虽然也是使用Java语言进行编程,但是在编译成CLASS文件后,还会通过一个工具(dx)将应用所有的 CLASS文件转换成一个DEX文件,而后Dalvik虚拟机会从其中读取指令和数据。

Dalvik和Android系统Android作为新一代的基于Linux的开源手机操作系统,其系统架构由下而上可以分为以下几部分:

  • Linux内核
  • 本地库
  • Android运行库
  • 应用框架
  • 应用

如上图所示,在Android的体系框架中有一部分叫做Android Runtime,即Android运行时环境,这个环境包括了两个部分,一个是Android的核心类库,还有一个就是Dalvik虚拟机了 。

如上图所示,jvm是把.java文本编译成.class字节码文件,在执行java程序的时候,类加载器把需要的类全部加载到内存当中去。

上图展示的是把字节码文件载入到内存后的结构,每个Class文件被解析成了几部分,包括了Header(主要是jdk的版本等)、常量等。有多少个类,就会在内存中产生多少个上图结构中的文件。


上图所示是dalvik虚拟机加载的类文件结构图。davik虚拟机把.java文件编译成.class文件,又把.class文件转换成.dex文件,dalvik来执行.dex文件。

实际上.dex文件就是把多个class文件中的常量、方法等放到一起。形成如上图所示的结构。每个类文件中都存在一个常量池,在dex文件中由一个常量池来管理。

在架构上jvm是基于栈的架构,所以每次访问数据cpu都要到内存中取到数据。

而dalvik是基于寄存器的架构。寄存器是在cpu上的一块存储空间,cpu如果直接从寄存器上读取数据的话就会快很多。

   java虚拟机和Dalvik虚拟机的区别:


java虚拟机Dalvik虚拟机
java虚拟机基于。 基于栈的机器必须使用指令来载入和操作栈上数据,所需指令更多更多dalvik虚拟机是基于寄存器
java虚拟机运行的是java字节码。(java类会被编译成一个或多个字节码.class文件,打包到.jar文件中,java虚拟机从相应的.class文件和.jar文件中获取相应的字节码)

 

Dalvik运行的是自定义的.dex字节码格式。(java类被编译成.class文件后,会通过一个dx工具将所有的.class文件转换成一个.dex文件,然后dalvik虚拟机会从其中读取指令和数据)

常量池已被修改为只使用32位的索引,以 简化解释器。dalvik的堆和栈的参数可以通过-Xms和-Xmx更改

一个应用,一个虚拟机实例,一个进程(所有android应用的线程都是对应一个linux线程,都运行在自己的沙盒中,不同的应用在不同的进程中运行。每个android dalvik应用程序都被赋予了一个独立的linux PID(app_*))


Dalvik和标准Java虚拟机(JVM)之间的首要差别之一,就是Dalvik基于寄存器,而JVM基于栈。
Dalvik和Java之间的另外一大区别就是运行环境——Dalvik经过优化,允许在有限的内存中同时运行多个虚拟机的实例,并且每一个 Dalvik应用作为一个独立的Linux进程执行。
(1)虚拟机很小,使用的空间也小;
(2)Dalvik没有JIT编译器;
(3)常量池已被修改为只使用32位的索引,以简化解释器;
(4)它使用自己的字节码,而非Java字节码。
(5)Dalvik适用于那些内存容量和数据处理能力比较小的机器,因此适合移动终端。由于delvik虚拟机指令都大多数都包含寄存器的地址,所以它的指令通常比java虚拟机的指令更长。一般而言基于栈的机器需要更多指令,而基于寄存器的机器指令更长。

基于栈和寄存器又有什么区别?

栈的概念

栈是线程独有的,保存其运行状态和局部自动变量的(所以多线程中局部变量都是相互独立的,不同于类变量)。栈在线程开始的时候初始化(线程的Start方法,初始化分配栈),每个线程的栈互相独立。每个函数都有自己的栈,栈被用来在函数之间传递参数。操作系统在切换线程的时候会自动的切换栈,就是切换SS/ESP寄存器。栈空间不需要在高级语言里面显式的分配和释放。

寄存器的概念:

寄存器是中央处理器内的组成部分。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和位址。在中央处理器的控制部件中,包含的寄存器有指令寄存器(IR)和程序计数器(PC),在中央处理器的算术及逻辑部件中,包含的寄存器有累加器(ACC)。

基于堆栈虚拟机实现,基于寄存器的虚拟机实现虽然在硬件通用性上要差一些,但是它在代码的执行效率却更胜一筹,虚拟机中指令的解释时间主要花在下面三个: 分发指令、访问运算数、执行运算, 其中分发指令这个环节对性能的影响最大。在基于寄存器的虚拟机里,可以更为有效的减少冗余指令的分发和减少内存的读写访问。

Dalvik虚拟机架构:

     在android源码中,Dalvik虚拟机的实现位于“dalvik/”目录下,其中“dalvik/vm”是虚拟机的实现部分,将会编译成libdvm.so;而"dalvik/libdex"将会编译成libdex.a静态库作为dex工具;“dalvik/dexdump”是.dex文件的反编译工具;虚拟机的可执行程序位于“dalvik/dalvikvm”中,将会编译成dalvikvm可执行文件。

  dalvik虚拟机架构:


Android应用编译及运行流程:


 Dalvik进程管理:

         dalvik进程管理是依赖于linux的进程体系结构的,如要为应用程序创建一个进程,它会使用linux的fork机制来复制一个进程(复制进程往往比创建进程效率更高)。

         Zygote是一个虚拟机进程,同时也是一个虚拟机实例的孵化器,它通过init进程启动。首先会孵化出System_Server(android绝大多系统服务的守护进程,它会监听socket等待请求命令,当有一个应用程序启动时,就会向它发出请求,zygote就会FORK出一个新的应用程序进程).每当系统要求执行一个android应用程序时,Zygote就会运用linux的FORK进制产生一个子进程来执行该应用程序。

 JVM和Dalvik进程管理:

        linux中进程间通信的方式有很多,但是dalvik使用的是信号方式来完成进程间通信。

Android的初始化流程


                

Dalvik 和 Java 运行环境的区别:                                                   

    1、Dalvik主要是完成对象生命周期管理,堆栈管理,线程管理,安全和异常管理,以及垃圾回收等等重要功能。   

     2、Dalvik负责进程隔离和线程管理,每一个Android应用在底层都会对应一个独立的Dalvik虚拟机实例,其代码在虚拟机的解释下得以执行。  

     3、不同于Java虚拟机运行java字节码,Dalvik虚拟机运行的是其专有的文件格式Dex。   

     4、dex文件格式可以减少整体文件尺寸,提高I/O操作的类查找速度。   

     5、odex是为了在运行过程中进一步提高性能,对dex文件的进一步优化。   

     6、每一个Android应用都运行在一个Dalvik虚拟机实例里,而每一个虚拟机实例都是一个独立的进程空间。虚拟机的线程机制,内存分配和管理,Mutex等等都是依赖底层操作系统而实现的。所有Android应用的线程都对应一个Linux线程,虚拟机因而可以更多的依赖操作系统的线程调度和管理机制   

     7、有一个特殊的虚拟机进程Zygote,他是虚拟机实例的孵化器。每当系统要求执行一个Android应用程序,Zygote就会FORK出一个子进程来执行该应用程序。它在系统启动的时候就会产生,它会完成虚拟机的初始化、库的加载、预置类库和初始化的操作。如果系统需要一个新的虚拟机实例,它会迅速复制自身,以最快的速度提供给系统。对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域。

打包成apk的过程:
Android应用所使用的编程语言是Java语言,和Java SE一样,编译时使用SunJDK将Java源程序编程成标准的Java字节码文件(.class文件),而后通过工具软件DX把所有的字节码文件转成DEX文件(classes.dex)。最后使用Android打包工具(aapt)将DEX文件、资源文件以及AndroidManifest.xml文件(二进制格式)组合成一个应用程序包(APK)。


0 0
原创粉丝点击