zoukankan      html  css  js  c++  java
  • Java虚拟接和Dalvik虚拟机的区别

    | java虚拟机                  | Dalvik                                              |
    |------------------------+------------------------------------     |
    | 基于堆栈                      | 基于寄存器                                       |
    |                                   | 透过zygote预加载类完成虚拟机的启动  |
    | 运行java字节码             | 运行dex字节码                                 |
    | 有218个机器指令          | 有200中机器指令                              |
    | 每个类中都有一个常量池 | 只有一个统一的常量池                        |
     
    Dalvik虚拟机主要是完成对象生命周期的管理,堆栈的管理,线程管理,安全和异常的管理,以及垃圾回收等等重要功能。
     
    Dalvik适用于那些内存容量和数据处理能力比较小的机器,因此适合移动终端。由于delvik虚拟机指令都大多数都包含寄存器的地址,所以它的指令通常比java虚拟机的指令更长。一般而言基于栈的机器需要更多指令,而基于寄存器的机器指令更长。
     
    Dalvik虚拟机的主要特征
    *专有的DEX文件格式*
    1. 一个应用中会定义很多类,编译完成后会形成很多的class文件,class文件之间有不少冗余信息,而dex文件格式会把所有的class文件全都整合到一块。这样除了减少了文件大小,便利I/O操作外,也加快了查找速度。原来每个类文件中都存在一个常量池,在dex文件中由一个常量池来管理。见上图
    2. 增加了新的操作码的支持
    3. 文件结构尽量简洁,使用等长的指令,提高解析速度
    4. 尽量扩大只读结构的大小,借以提高进程的数据共享
    5. 如何生成dex文件呢

    java字节码文件由多个.class文件组成,在运行期间虚拟机会从相应的.class文件中加载相应类,而Dalvik字节码只由一个.dex文件组成,它包括了应用的所有类。.dex文件形成的过程: java编译器编译java源文件形成.class字节码文件,Dalvik dx编译器删除所有的.class文件,并把它们重新编译成Dalvik字节码文件,之后dx编译器把它们合成一个.dex文件。
     
    原来每个类文件中都存在一个常量池,在dex文件中由一个常量池来管理。
     
    *DEX优化*
    1. 调整所有字段的字节序和对其结构中的每一个域
    2. 验证DEX文件中的所有类
    3. 对一些特定的类进行优化,对方法里的操作码进行优化
    由于dex文件的结构是紧凑的,所有优化之后文件的大小会有所增减,大概是原来文件的1-4倍。
     
    优化发生的时机有两个:对于预置应用,可以在系统编译后,生成优化文件,以ODEX结尾。这样在发布时除APK文件(不包含DEX)以外,还有一个相应的ODEX文件;对于非预置应用,包含在APK文件里的DEX文件会在运行时被优化,优化后的文件将被保存在缓存中。
     
    *指令集基于寄存器*
    基于堆栈虚拟机实现,基于寄存器的虚拟机实现虽然在硬件通用性上要差一些,但是它在代码的执行效率却更胜一筹,虚拟机中指令的解释时间主要花在下面三个: 分发指令、访问运算数、执行运算, 其中分发指令这个环节对性能的影响最大。在基于寄存器的虚拟机里,可以更为有效的减少冗余指令的分发和减少内存的读写访问。
     
    *一个应用,一个虚拟机实例,一个进程*
    每一个Android应用都运行在一个Dalvik虚拟机实例里,而每一个虚拟机实例都是一个独立的进程空间。虚拟机的线程机制,内存分配和管理,Mutex等等都是依赖底层操作系统而实现的。所有Android应用的线程都对应一个Linux线程,虚拟机因而可以更多的依赖操作系统的线程调度和管理机制
     
    不同的应用在不同的进程空间里运行,加之对不同来源的应用都使用不同的Linux用户来运行,可以最大程度的保护应用的安全和独立运行
     
    Zygote是一个虚拟机进程,同时也是一个虚拟机实例的孵化器,每当系统要求执行一个Android应用程序,Zygote就会FORK出一个子进程来执行该应用程序。这样做的好处显而易见:Zygote进程是在系统启动时产生的,它会完成虚拟机的初始化,库的加载,预置类库的加载和初始化等等操作,而在系统需要一个新的虚拟机实例时,Zygote通过复制自身,最快速的提供给系统。另外,对于一些只读的系统库,所有虚拟机实例都和Zygote共享一块内存区域,大大节省了内存开销。
     
    应用程序包被发布到手机上后,运行前会对其中的dex文件进行优化,优化后的文件被保存在缓冲区(优化后的格式被称为dey),虚拟机会直接执行该文件,如果应用包文件不发生变化,dey文件不会被重新生成。
     

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

     
  • 相关阅读:
    读入输出优化
    【JSOI2008】星球大战 并查集
    堆STL和重载运算符
    树的直径
    H3C三层交换机(S5500)清除配置信息并进行简单配置
    简单的逻辑学
    Java基础--第十八天
    Java基础--第十七天
    Java基础--第十六天
    Java基础--第十五天
  • 原文地址:https://www.cnblogs.com/qianye/p/2786316.html
Copyright © 2011-2022 走看看