关于Dalvik、ART、DEX、JIT、AOT

1. Dalvik&ART

1.1 Dalvik

Dalvik是Google公司自己设计用于Android平台的虚拟机。DVM即Dalvik Virtual Machine的缩写,那么DVM和JVM有什么区别呢?

  1. DVM基于寄存器,JVM基于栈

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

  2. 执行的字节码文件不一样

    DVM执行的是.dex文件,JVM执行的是.class文件。

    AVM解释执行的是dex字节码.dex:.java –> .class –> .dex –> .apk

    JVM运行的是java字节码.class:.java –> .class –> .jar

  3. 运行环境的区别

    DVM:允许运行多个虚拟机实例,每一个应用启动都运行一个单独的虚拟机,并且运行在一个独立的进程中

    JVM:只能运行一个实例,也就是所有应用都运行在同一个JVM中

1.2 ART

ART即Android Runtime,是在Dalvik的基础上做了一些优化。在Dalvik下,应用每次运行的时候,字节码都需要通过即时编译器(JIT, just in time)转换为机器码,这会拖慢应用的运行效率,而在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。这个过程叫做预编译(AOT, Ahead-Of-Time)。这样的话,应用的启动(首次)和执行都会变得更加快速。

ART虚拟机执行的本地机器码:

.java –> java bytecode(.class) –> dalvik bytecode(.dex) –> optimized android runtime machine code(.oat)

1.3 Dalvik和ART区别

Dalvik是运行时解释dex文件,安装比较快,开启应用比较慢,应用占用空间小;ART是安装的时候字节码预编译成机器码存储在本地,执行的时候直接就可以运行的,安装慢,开启应用快,占用空间大;

比较喜欢一个骑自行车的例子,Dalvik好比一个已经折叠起来的自行车,每次骑之前都要先组装才能骑,ART相当于一个已经组装好的自行车,每次直接骑着就走了。

2. dex&odex&oat

2.1 dex

dex(Dalvik Executable),本质上java文件编译后都是字节码,只不过JVM运行的是.class字节码,而DVM运行的是.dex字节码,sdk\build-tools\25.0.2\dx工具负责将Java字节码.class文件转换为Dalvik字节码.dex,dx工具对Java类文件重新排列,消除在类文件中出现的所有冗余信息,避免虚拟机在初始化时出现反复的文件加载与解析过程。一般情况下,Java类文件中包含多个不同的方法签名,如果其他的类文件引用该类文件中的方法,方法签名也会被复制到其类文件中,也就是说,多个不同的类会同时包含相同的方法签名,同样地,大量的字符串常量在多个类文件中也被重复使用。这些冗余信息会直接增加文件的体积,同时也会严重影响虚拟机解析文件的效率。消除其中的冗余信息,重新组合形成一个常量池,所有的类文件共享同一个常量池,由于dx工具对常量池的压缩,使得相同的字符串,常量在DEX文件中只出现一次,从而减小了文件的体积,同时也提高了类的查找速度,此外,dex格式文件增加了新的操作码支持,文件结构也相对简洁,使用等长的指令来提高解析速度。

2.2 odex

odex(Optimized dex),即优化的dex,主要是为了提高DVM的运行速度,在编译打包APK时,Java类会被编译成一个或者多个字节码文件(.class),通过dx工具CLASS文件转换成一个DEX(Dalvik Executable)文件。 通常情况下,我们看到的Android应用程序实际上是一个以.apk为后缀名的压缩文件。我们可以通过压缩工具对apk进行解压,解压出来的内容中有一个名为classes.dex的文件。那么我们首次开机的时候系统需要将其从apk中解压出来保存在data/app目录中。 如果当前运行在Dalvik虚拟机下,Dalvik会对classes.dex进行一次“翻译”,“翻译”的过程也就是守护进程installd的函数dexopt来对dex字节码进行优化,实际上也就是由dex文件生成odex文件,最终odex文件被保存在手机的VM缓存目录data/dalvik-cache下(注意!这里所生成的odex文件依旧是以dex为后缀名,格式如:system@priv-app@Settings@Settings.apk@classes.dex)。如果当前运行于ART模式下, ART同样会在首次进入系统的时候调用/system/bin/dexopt(此处应该是dex2oat工具吧)工具来将dex字节码翻译成本地机器码,保存在data/dalvik-cache下。 那么这里需要注意的是,无论是对dex字节码进行优化,还是将dex字节码翻译成本地机器码,最终得到的结果都是保存在相同名称的一个odex文件里面的,但是前者对应的是一个.dex文件(表示这是一个优化过的dex),后者对应的是一个.oat文件。通过这种方式,原来任何通过绝对路径引用了该odex文件的代码就都不需要修改了。 由于在系统首次启动时会对应用进行安装,那么在预置APK比较多的情况下,将会大大增加系统首次启动的时间。

从前面的描述可知,既然无论是DVM还是ART,对DEX的优化结果都是保存在一个相同名称的odex文件,那么如果我们把这两个过程在ROM编译的时候预处理提取Odex文件将会大大优化系统首次启动的时间。具体做法则是在device目录下的/device/huawei/angler/BoardConfig.mk中定义WITH_DEXPREOPT := true,打开这个宏之后,无论是有源码还是无源码的预置apk预编译时都会提取odex文件,不过这里需要注意的是打开WITH_DEXPREOPT 宏之后,预编译时提取Odex会增加一定的空间,预置太多apk,会导致system.img 过大,而编译不过。遇到这种情况可以通过删除apk中的dex文件、调大system.img的大小限制,或在预编译时跳过一些apk的odex提取。
2.3 oat
oat文件是ART的核心,是通过/system/bin/dex2oat 工具生成的,实际上是一个自定义的elf文件,里面包含的都是本地机器指令,通过AOT生成的文件,在系统中的表现形式有OAT、ART、ODEX,其中大部分apk在执行AOT后生成的都是odex文件。但是由dex2oat工具生成的oat文件包含有两个特殊的段oatdata和oatexec,前者包含有用来生成本地机器指令的dex文件内容,后者包含有生成的本地机器指令,进而就可以直接运行。其是通过PMS –> installd –> dex2oat的流程生成的,可以在预编译的时候,也可以在开机apk扫描的过程中或者apk安装过程中生成。

3. JIT&AOT

3.1 JIT

JIT(Just In Time Compiler, 即时编译),与Dalvik虚拟机相关。

JIT在2.2版本提出的,目的是为了提高android的运行速度,一直存活到4.4版本,因为在4.4之后的ROM中,就不存在Dalvik虚拟机了。我们使用Java开发android,在编译打包APK文件时,会经过以下流程:

  1. Java编译器将应用中所有Java文件编译为class文件
  2. dx工具将应用编译输出的类文件转换为Dalvik字节码,即dex文件

DVM负责解释dex文件为机器码,如果我们不做处理的话,每次执行代码,都需要Dalvik将java代码由解释器(Interpreter)将每个java指令转译为微处理器指令,并根据转译后的指令先后次序依序执行,一条java指令可能对应多条微处理器指令,这样效率不高。为了解决这个问题,Google在2.2版本添加了JIT编译器,当App运行时,每当遇到一个新类,JIT编译器就会对这个类进行编译,经过编译后的代码,会被优化成相当精简的原生型指令码(即native code),这样在下次执行到相同逻辑的时候,速度就会更快。但是使用JIT也不一定加快执行速度,如果大部分代码的执行次数很少,那么编译花费的时间不一定少于执行dex的时间。Google当然也知道这一点,所以JIT不对所有dex代码进行编译,而是只编译执行次数较多的dex为本地机器码。

3.2 AOT

AOT(Ahead Of Time),和ART虚拟机相关。

JIT是运行时编译,这样可以对执行次数频繁的dex代码进行编译和优化,减少以后使用时的翻译时间,虽然可以加快Dalvik运行速度,但是还是有弊病,那就是将dex翻译为本地机器码也要占用时间,所以Google在4.4之后推出了ART,用来替换Dalvik。

在4.4版本上,两种运行时环境共存,可以相互切换,但是在5.0+,Dalvik虚拟机则被彻底的丢弃,全部采用ART。ART的策略与Dalvik不同,在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。之后打开App的时候,不需要额外的翻译工作,直接使用本地机器码运行,因此运行速度提高。

总的来说:

  • JIT代表运行时编译策略,也可以理解成一种运行时编译器,是为了加快Dalvik虚拟机解释dex速度提出的一种技术方案,来缓存频繁使用的本地机器码
  • AOT可以理解运行前编译策略,ART虚拟机的主要特征就是AOT

4. Android N上的改变

4.1 ART缺点

  • dex->oat生成时间太久,进而apk安装时间很久
  • dex2oat耗用系统资源太多,特别dex2oat占用cpu和memory
  • oat文件过大,rom小的设备data空间会吃紧
  • Powerconsumption 增加
  • ART不太稳定,在M上crash问题太多,debug不太容易
  • oat文件是elf格式,所以加载oat文件时候相关依赖库也很多,间接导致app进程占用Memory的增加

9102年了,还不知道Android为什么卡?

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容