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

Dalvik虚拟机和Art虚拟机的更多相关文章

  1. Android内存优化(一)Dalvik虚拟机和ART虚拟机对比

    1.概述 Android4.4以上开始使用ART虚拟机,在此之前我们一直使用的Dalvik虚拟机,那么为什么Google突然换了Android运行的虚拟机呢?答案只有一个:ART虚拟机更优秀. 2.D ...

  2. JAVA虚拟机、Dalvik虚拟机和ART虚拟机简要对比

    1.什么是JVM?   JVM本质上就是一个软件,是计算机硬件的一层软件抽象,在这之上才能够运行Java程序,JAVA在编译后会生成类似于汇编语言的JVM字节码,与C语言编译后产生的汇编语言不同的是, ...

  3. JAVA虚拟机、Dalvik虚拟机和ART虚拟机简要对照

    1.什么是JVM? JVM本质上就是一个软件,是计算机硬件的一层软件抽象,在这之上才干够运行Java程序,JAVA在编译后会生成相似于汇编语言的JVM字节码,与C语言编译后产生的汇编语言不同的是,C编 ...

  4. 传统的Java虚拟机和Android的Dalvik虚拟机及其ART模式

    Java虚拟机的解释执行引擎称为“基于栈的执行引擎”,其中所指的“栈”就是操作数栈.因此我们也称Java虚拟机是基于栈的,这点不同于Android虚拟机,Android虚拟机是基于寄存器的. 基于栈的 ...

  5. art虚拟机介绍

    Android 4.4提供了一种与Dalvik截然不同的运行环境ART(Android runtime)支持,ART源于google收购的Flexycore的公司.ART模式与Dalvik模式最大的不 ...

  6. ART虚拟机之Trace原理(转)

    一.概述 Android 6.0系统采用的art虚拟机,所有的Java进程都运行在art之上,当应用发生ANR(Application Not Response,其中最终的一个环节便是向目标进程发送信 ...

  7. DexHunter在ART虚拟机模式下的脱壳原理分析

    本文博客地址: http://blog.csdn.net/qq1084283172/article/details/78494620 DexHunter脱壳工具在Dalvik虚拟机模式下的脱壳原理分析 ...

  8. 实战Java虚拟机之二“虚拟机的工作模式”

    今天开始实战Java虚拟机之二:“虚拟机的工作模式”. 总计有5个系列 实战Java虚拟机之一“堆溢出处理” 实战Java虚拟机之二“虚拟机的工作模式” 实战Java虚拟机之三“G1的新生代GC” 实 ...

  9. 【虚拟机】苹果虚拟机mac10.11.6+Xcode8.1

    [虚拟机]苹果虚拟机mac10.11.6+Xcode8.1本虚拟机加装Xcode8.1,方便大家更好学习Swift3.0语言以及iOS开发.安装注意事项:第一步:确认硬件:1.确认主板以及cpu支持虚 ...

随机推荐

  1. 自用代码css获取任意网址的/favicon.ico的方法教程

    尝试过使用网友说的API接口获取 找到的都是失效了 暂时就使用这种办法获取 如果有好的方法望评论告知 谢谢 <img :ng-src="'http://'+list.url+'/fav ...

  2. epel-release的卸载重装

    1.yum remove epel-release 2.清空epel目录:rm -rf /var/cache/yum/x86_64/6/epel/ 3.安装,yum install  epel-rel ...

  3. HDU Queuing(递推+矩阵快速幂)

    Queuing Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  4. Spring注解开发系列Ⅰ--- 组件注册(上)

    传统的Spring做法是使用.xml文件来对bean进行注入或者是配置aop.事物,这么做有两个缺点:1.如果所有的内容都配置在.xml文件中,那么.xml文件将会十分庞大:如果按需求分开.xml文件 ...

  5. linux 内存使用分析

      查看当前内存使用情况,最常用的指令就是 [root@t ~]# free -m total used free shared buffers cached Mem: -/+ buffers/cac ...

  6. 理解和运用Java中的Lambda

    前提 回想一下,JDK8是2014年发布正式版的,到现在为(2020-02-08)止已经过去了5年多.JDK8引入的两个比较强大的新特性是Lambda表达式(下文的Lambda特指JDK提供的Lamb ...

  7. 读取纯真IP数据库

    #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <string> #include <stdli ...

  8. WeChall_Prime Factory (Training, Math)Training: WWW-Robots (HTTP, Training)

    In this little training challenge, you are going to learn about the Robots_exclusion_standard.The ro ...

  9. 《数据结构与算法分析-Java语言描述》 分享下载

    书籍信息 书名:<数据结构与算法分析-Java语言描述> 原作名:Data Structures and Algorithm Analysis in Java 作者: 韦斯 (Mark A ...

  10. C++用rand()和srand()生成随机数

    内容来自<编程实战宝典> 首先来看函数原型 int rand(void); void srand(unsigned int seed); 1.rand()函数不需要任何参数,直接返回一个随 ...