Dalvik虚拟机

DVM是Dalvik Virtual Machine的缩写,是Android4.4及以前使用的虚拟机,所有android程序都运行在android系统进程里,每个进程对应着一个Dalvik虚拟机实例。

DVM和JVM的区别

  1. 执行的字节码不同

    • JAVA虚拟机运行的是JAVA字节码,Dalvik虚拟机运行的是Dalvik字节码
     JVM: .java -> javac -> .class -> jar -> .jar
    DVM: .java -> javac -> .class -> dx.bat -> .dex
    • Dalvik可执行文件体积更小

      一般情况下,Java类文件中包含多个不同的方法签名,如果其他的类文件引用该类文件中的方法,方法签名也会被复制到其类文件中,也就是说,多个不同的类会同时包含相同的方法签名,同样地,大量的字符串常量在多个类文件中也被重复使用。这些冗余信息会直接增加文件的体积,同时也会严重影响虚拟机解析文件的效率。

      安卓使用Dalvik虚拟机,SDK中有个dx工具负责将JAVA字节码转换为Dalvik字节码,dx工具对JAVA类文件重新排列,将所有JAVA类文件中的常量池分解,消除其中的冗余信息,重新组合形成一个常量池,所有的类文件共享同一个常量池,使得相同的字符串、常量在DEX文件中只出现一次,从而减小了文件的体积。
  2. 基于的架构不同

    Dvm基于寄存器,所以它的指令是二地址和三地址混合,指令中指明了操作数的地址;jvm基于栈,它的指令是零地址,指令的操作数对象默认是操作数栈中的几个位置。但基于寄存器的指令由于需要指定源地址和目标地址,因此需要占用更多的指令空间。

    Java虚拟机基于栈架构。程序在运行时虚拟机需要频繁的从栈上读取或写入数据,这个过程需要更多的指令分派与内存访问次数, 会耗费不少CPU时间, 对千像手机设备资源有限的设备来说, 这是相当大的一笔开销。Dalvik 虚拟机基于寄存器架构。数据的访问通过寄存器间直接传递, 这样的访问方式比基千栈方式要快很多。

Dalvik堆

Dalvik虚拟机用来分配对象的堆划分为两部分,一部分叫做Active Heap,另一部分叫做Zygote Heap。Android系统启动后,会有一个Zygote进程创建第一个Dalvik虚拟机,它只维护了一个堆。以后启动的所有应用程序进程是被Zygote进程fork出来的,并都持有一个自己的Dalvik虚拟机。在创建应用程序的过程中,Dalvik虚拟机采用COW策略复制Zygote进程的地址空间。

当创建第一个应用程序进程时,会将已经使用了的那部分堆内存划分为一部分,还没有使用的堆内存划分为另外一部分。前者就称为Zygote堆,后者就称为Active堆。这样只需把zygote堆中的内容复制给应用程序进程就可以了。以后无论是Zygote进程,还是应用程序进程,当它们需要分配对象的时候,都在Active堆上进行。这样就可以使得Zygote堆尽可能少地被执行写操作,因而就可以减少执行写时拷贝的操作。在Zygote堆里面分配的对象其实主要就是Zygote进程在启动过程中预加载的类、资源和对象了。这意味着这些预加载的类、资源和对象可以在Zygote进程和应用程序进程中做到长期共享。这样既能减少拷贝操作,还能减少对内存的需求。Dalvik虚拟机进行部分垃圾收集时,实际上就是只收集在Active堆上分配的对象。

Art虚拟机

为了区分Art虚拟机和Dalvik虚拟机,需要先介绍下面两个概念。

  • JIT

    JIT(Just-in-time Compilation,即时编译),又称为动态编译,是一种通过在运行时将字节码翻译为机器码的技术,使得程序的执行速度更快。

    在JVM中,javac将源程序编译成java字节码,JVM通过逐条解释将字节码翻译成对应的机器指令,逐条读入,逐条解释翻译,比较慢;为了提升速度,当App运行时,每当遇到一个新类,JIT编译器就会对这个类进行编译,经过编译后的代码,会被优化成相当精简的原生型指令码(即native code),这样在下次执行到相同逻辑的时候,速度就会更快。

    但是,有一点需要注意,dex字节码翻译成本地机器码是发生在应用程序的运行过程中的,并且应用程序每一次重新运行的时候,都要做重做这个翻译工作,每次重新打开App,都需要JIT编译。

  • AOT

    ART的策略与Dalvik不同,在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。APK在安装的时候,打包在里面的classes.dex文件会被工具dex2oat翻译成本地机器指令,最终得到一个ELF格式的oat文件。

    这样可以保证以后每次打开应用,执行的都是本地机器码。去除了运行时的解释执行,效率更高,启动更快。

  • ART和Dalvik的区别

    1. ART需要应用程序在安装时,就把程序代码转换成机器语言,所以这会消耗掉更多的存储空间,但消耗掉空间的增幅通常不会超过应用代码包大小的20%
    2. 由于有了一个转码的过程,所以应用安装时间难免会延长

参考文章:

  1. https://www.jianshu.com/p/156a71091333
  2. https://www.jianshu.com/p/713d24fa9982
  3. https://blog.csdn.net/computer30000/article/details/79941151

最新文章

  1. IBatis 2.x 和 MyBatis 3.0.x 的区别(从 iBatis 到 MyBatis)
  2. eclipse 引用项目(转)
  3. Rsa加解密Java、C#、php通用代码 密钥转换工具
  4. Verilog之基本算数运算
  5. .Net 内存溢出(System.OutOfMemoryException)的常见情况和处理方式总结
  6. win7下环境搭建
  7. unix环境C编程之日期时间转换
  8. TortoiseSVN 插件配置及使用方法
  9. Python默认编码错误SyntaxError: Non-ASCII character '\xe5'之解决方法
  10. 《REWORK》启示录 招聘笔杆子——程序员为什么值得写博客
  11. Orace数据库锁表的处理与总结<摘抄与总结二>
  12. js身份证验证代码
  13. 本地ssh连接到vbox中的linux
  14. Android几行代码实现实时监听微信聊天
  15. vue打包上传oss
  16. MySQL将查询出来的一组数据拼装成一个字符串
  17. SDRAM单字写操作
  18. .NET Core 获取配置文件appsettings.json 方法
  19. html5 canvas旋转+缩放
  20. Spring RestTemplate中几种常见的请求方式GET请求 POST请求 PUT请求 DELETE请求

热门文章

  1. 自定义BeanDefinitionRegistryPostProcessor
  2. 自定义BeanDefinitionRegistryPostProcessor注册bean
  3. ios--->上下拉刷新控件MJRefresh
  4. Python经典算法-快速幂
  5. 关于Influxdb1.4.2在windows下的安装过程的一些问题的记录
  6. FPGA基础知识关键点摘要
  7. python strip()方法使用
  8. 90万条数据玩转RFM用户分析模型
  9. ORACLE隐式类型转换
  10. HDU 6274 Master of Sequence (暴力+下整除)