Dalvik和ART
这是我第三次写Dalvik(以下简称DVM)和ART虚拟机了,它们都是Android手机上运行java代码的虚拟虚拟机。DVM不是JVM,主要还是因为DVM的实现没有遵守JVM的实现规范。
DVM与JVM基于的架构不同
JVM是基于栈的,当它需要到栈中去读写数据时,所需的指令就因此而增多,将导致速度变慢。手机的使用要求就是要快,显然JVM是不能满足这一性能要求。所以google就用Dalvik来解决这个性能问题。DVM是基于寄存器,因此它不需要像JVM那样在复制数据时要使用大量的出入栈指令。不过因为DVM由于显式指定了操作数,因此DVM基于寄存器的指令会比基于栈的指令要大,同时也因此减少了指令的数量。
DVM与JVM执行字节码的方式不同
在Java SE程序中,Java类被编译成一个或多个.class文件,并打包成.jar文件,程序运行时,JVM会通过相应的.class文件和jar文件获取相应的字节码。它的顺序是.java文件->.class文件->.jar文件。
.jar文件里面包含多个.class文件,每个.class文件里面包含了该类的常量池、类信息、属性等,当JVM加载该.jar文件时,会加载里面所有的.class文件,JVM这种加载方式很慢,对于内存有限制的移动设备来说非常不合适的。
而DVM则是用dx工具将所有的.class文件转换为一个.dex文件,当应用程序运行时,DVM会从该.dex文件读取指令和数据。它的顺序是.java文件->.class文件->.dex文件。apk文件里面只包含了一个.dex文件,这个.dex文件将所有的.class文件里面所包含的信息全部都整合在一起了。这样加载速度会快很多。.dex文件由类加载器处理,接着解释器根据指令集对Dalvik字节码进行解释、执行,最后交给Linux处理。另外,.class文件会有很多冗余信息,dex工具会去除冗余信息,并把所有.class文件整合到.dex文件中,可以减少I/O操作,加快了类的查找速度。
一个应用程序对应一个DVM实例
在Android中的每一个应用都运行在一个DVM实例中,而每一个DVM实例都运行在一个独立的进程空间中,独立的进程可以防止在虚拟机崩溃的时候所有程序都被关闭。
DVM是由Zygote创建和初始化
Zygote进程本身也是一个DVM进程。它同时也是用来创建和初始化DVM实例的。每当系统需要创建一个应用程序时,Zygote进程就fork自身(其就是复制自己,用了写时复制),快速地创建和初始化一个DVM实例,用于应用程序的运行。对于一些只读的系统库,所有的DVM实例都会和Zygote共享一块内存区域,从而节省了内存开销。
DVM与JIT(即时编译)
DVM还没有加入JIT功能时,DVM每次执行代码,都需要通过解释器将.dex编译成机器码,然后交给系统处理,但效率不高。为了提高效率,在Android2.2后就加入了JIT,它会对多次运行的代码(热点代码)进行编译,生成相当精简的本地机器码,这样下次执行到相同逻辑时,就可以直接使用编译之后的本地机器码,而不是每次都需要编译。不过,需要注意的是:应用程序每一次重新运行的时候,都需要重新做这个编译工作 ,因此每次重新打开应用程序,都需要JIT编译。
DVM的运行时堆
DVM的运行堆使用标记-清除算法进行GC,由两个Space和多个辅助数据结构组成。两个Space分别是Zygote Space(Zygote Heap)和Allocation Space(Active Heap)。Zygote Space用来管理Zygote进程在启动过程中预加载和创建的各种对象,它不会触发GC。在Zygote进程和应用程序之间会共享Zygote Space。在Zygote进程fork第一个子进程之前,会把Zygote Space分成两个部分,原来的已经被使用的那部分仍旧叫Zygote Space,而未使用那一个部分则就叫Allocation Space,以后的对象都会在Allocation Space上进行分配和释放。Allcation Space不是进程间共享的,在每个进程中都独立拥有一份。除了这两个Space,还有以下的辅助数据结构:
- Card Table:当第一个次进程垃圾标记后,记录垃圾信息
- Heap Bitmap:有两个Heap Bitmap,一个用来记录上次GC存活的对象 ,另一个用来记录这次GC存活的对象。
- Mark Stack:在GC标记的阶段使用,它用来遍历存活象。
ART的时代
在Android4.4时,发布了ART虚拟机,用来替代Dalvik虚拟机,但anroid4.4上默认还是运行Dalvik。Android 5.0后才默认使用ART虚拟机。
ART与DVM的区别
- DVM是为32位CPU设计的(注定会被淘汰),而ART支持64位并且兼容32位CPU
- ART将GC暂停由2次改为1次
- ART的运行时堆与DVM不同
- DVM中的应用每次运行时,字节码都需要通过JIT编译器编译为机器码,这会使用应用程序的运行效率降低,在ART中,系统在安装应用时会进行一次AOT(ahead of time compilation,预编译),将字节码预先编译成机器码并存储在本地,这样应用程序运行时就不需要执行编译了,运行效率会大大提升,设备的耗电也会降低。采用AOT也会有缺点,主要有两个:(1)AOT会使得应用程序的安装时间变长,尤其是一些复杂的应用;(2)字节码预先编译成机器码,机器码需要的存储空间会多一些。为了解决这两个问题,在Android7.0中的ART加入了JIT,作为AOT的一个补充,在应用程序安装时并不会将字节码全部编译成机器码,而是在运行中将热点代码编译成机器码,从而缩短应用程序安装时间并节省了存储空间。
ART的运行时堆
与DVM的GC不同,ART采用了多种垃圾收集方案,每个方案会运行不同的垃圾收集器,默认是采用了CMS(Concurrent Mark-Sweep)方案,该方案主要使用了sticky-CMS和partial-CMS。根据不同的CMS方案,ART的运行时堆的空间也会有不同的划分,默认是由4个Space和多个辅助数据结构组成的。4个Space分别是Zygote Space、Allocation Space、Image Space、Large Object Space。Zygote Space、Allocation Space和DVM是一样的。Image Space是用来存放 一些预加载类,Large Object Space用来分配一些大对象。其中 Zygote Space和Image Space是进程间共享的。除了这四个Space,ART的Java堆中还包括两个Mod Union Table,一个Card Table、两个Heap Bitmap,两个Object Map,以及三个Object Stack。
谢谢阅读。
Dalvik和ART相关推荐
- Android .dex、.odex、Dalvik、ART、AOT、OAT
文章来源:https://www.jianshu.com/p/e52b7e460748 https://zhuanlan.zhihu.com/p/53723652 目的 理清 .dex..odex.A ...
- Android Dalvik、ART及APK编译过程
强烈建议看罗升阳大神的文章,五年过去,回头看,真的还是经典啊,不要认为几年前的文章没有价值,看一看就知道 妙啊: https://blog.csdn.net/Luoshengyang/article/ ...
- Dalvik和ART的区别
Dalvik和ART的区别 Dalvik环境下,应用每次运行时,字节码都需要通过即时编译器(Just In Time,JIT)转换为机器码,这样每次应用启动的速度就会非常的慢.ART环境中,应用会在安 ...
- Dalvik与ART区别屋
一.Dalvik和ART区别 Dalvik环境中,应用每次运行时, 字节码都需要通过即时编译器JIT(Just In Time ,)转换为机器码.ART环境中,应用会在安装的时候就将字节码预编译A ...
- Android之Dalvik 、ART
Dalvik和ART都是Android的虚拟机(VM),Dalvik是Android 5.0(2014年)之前使用的,ART是Android 5.0开始采用的. Dalvik的执行引擎采用的编译执行( ...
- Dalvik与ART的GC调试
本文主要讲述Dalvik与ART两种Android虚拟机,在GC时产生log信息的含义,便于分析. 一.Dalvik虚拟机 1.1 GC log格式 Dalvik虚拟机,每一次GC打印内容: 格式: ...
- android odex版本调试_android 基础-Dalvik ,ART,JIT,AOT,Dex,Odex
Dalvik 和 ART Dalvik:Dalvik 虚拟机,android 5.0 以前所使用的虚拟机,可执行文件为 dex 格式,基于寄存器的虚拟机(jvm 基于堆栈).通过 dx 工具将 .cl ...
- dalvik 与art 区别
Dalvik 模式应该是在Dalvik虚拟机里对程序代码进行解析,这样的话每次运行软件都会启动Dalvik 虚拟机,然后对软件代码进行 解析,简单的说处理一个程序需要启动两个程序,但是在安装软件的时候 ...
- 安卓dalvik和art区别
Dalvik模式像是一台折叠自行车,每次骑之前都要组装后才能上路.而ART模式就是一个已经装好的自行车,直接就能上车走人.所以ART模式在效率上肯定是要好于Dalvik. 通过以上这种表格,我们可以直 ...
- Android 系统性能优化(25)---Dalvik 与ART
前言 要学习Android的内存优化,首先要了解Java虚拟机,此前我用了多篇文章来介绍Java虚拟机的知识,就是为了这个系列做铺垫.在Android开发中我们接触的是与Java虚拟机类似的Dalvi ...
最新文章
- 简述systemd的新特性及unit常见类型分析、使用systemd管理编译安装的nginx
- u盘 linux centos 5.3,鸟哥linux私房菜学习笔记,U盘安装centos5.3不能正常进入图形界面的问题...
- php xml数据拼接,在PHP中合并XML文件
- (2021) 23 [持久化] I/O设备与驱动
- 三万字速通SSM框架入门知识点,快速上手CRUD
- C 语言 运算符怎么使用,详解C++编程中运算符的使用
- 【Java】京东面试:说说MySQL的架构体系
- MySQL 主从复制 复制过滤
- crypto在web的使用
- 第 14 篇:交流的桥梁“评论功能”——HelloDjango 系列教程
- 设计模式——责任链模式(职责链模式)
- 攻防世界--logmein
- Three.js加载OBJ模型或FBX模型
- 人工智能领域专业术语合集
- 攻防世界web新手题答案_南开本部20春学期(2003)《计算机应用基础》在线作业-1答案...
- 10 款牛哄哄的 Chrome 插件
- 企业WiFi管理解决方案
- 解决PPPOE宽带拨号经常掉线的一种…
- MapReduce自定义Job示例一:高温统计
- 芯片测试术语 ,片内测试(BIST),ATE测试