Android Dalvik,ART虚拟机

一. java平台的虚拟机Jvm

1. jvm的作用

Java语言的一个非常重要的特点就是与平台的无关性(跨平台性),我们经常会听到一句关于java特性的话:"一次编译到处执行"。由于机器只能识别机器码,所以需要通过Java 编译器将 .java 文件转换成 .class文件,也就是字节码文件。最终将字节码提供给 JVM,由 JVM 将它转换成机器码。

2. jvm分析

jvm相关知识体系过于庞大,有兴趣可以看本人之前的文章:JAVA JVM详解

二. Dalvik虚拟机

1. 为什么Android平台不使用标准的Jvm虚拟机?

由于 Androd 运行在移动设备上,内存以及电量等诸多方面跟一般的 PC 设备都有本质的区别 ,一般的 JVM 没法满足移动设备的要求,所以Android 团队一开始就打造了一个符合移动设备的可以执行 Java 代码的虚拟机。这就是我们说的 Dalvik 虚拟机 。

2. Android平台Dalvik的特点。

  • 体积小,占用内存空间小;
  • 专有的DEX可执行文件格式,体积更小,执行速度更快;
  • 基于寄存器架构,并拥有一套完整的指令系统;
  • android为每个应用程序提供一个Dalvik虚拟机,可以使每个app都运行在独立的虚拟机运行环境,使稳定性提高。使得应用代码和核心的操作系统分开。即使任意一个程序中包含恶意的代码也不会直接影响系统文件。这使得 Android 操作系统更稳定可靠。

3. jvm和Dalvik的区别。

相同点:

  • 都是解释执行。
  • 都是每个 OS 进程运行一个 VM,并运行一个单独的程序。
  • (Android Froyo / Sun JDK 1.5)都实现了相当程度的 JIT compiler(即时编译) 用于提速。JIT(Just In Time,即时编译技术)对于热代码(使用频率高的字节码)直接转换成汇编代码;

不同点:

  • Dalvik执行的是.dex格式文件,jvm执行的是.class文件。多个class文件转变成一个dex文件会引发一些问题,具体如下:

    1. 方法数受限:多个class文件变成一个dex文件所带来的问题就是方法数超过65535时报错,由此引出MultiDex技术。
    2. class文件去冗余:class文件存在很多的冗余信息,dex工具会去除冗余信息(多个class中的字符串常量合并为一个,比如对于Ljava/lang/Oject字符常量,每个class文件基本都有该字符常量,存在很大的冗余),并把所有的.class文件整合到.dex文件中。减少了I/O操作,提高了类的查找速度。
  • JVM是基于栈,Dalvik指令集是基于寄存器的架构。具体如下:

    1. Dalvik速度快!寄存器存取速度比栈快的多,Dalvik可以根据硬件实现最大的优化,比较适合移动设备。JAVA虚拟机基于栈结构,程序在运行时虚拟机需要频繁的从栈上读取写入数据,这个过程需要更多的指令分派与内存访问次数,会耗费很多CPU时间。
    2. 指令数小!Dalvik基于寄存器,所以它的指令是二地址和三地址混合,指令中指明了操作数的地址;jvm基于栈,它的指令是零地址,指令的操作数对象默认是操作数栈中的几个位置。这样带来的结果就是Dalvik的指令数相对于jvm的指令数会小很多,jvm需要多条指令而Dalvik可能只需要一条指令。
    3. jvm基于栈带来的好处是可以做的足够简单,真正的跨平台,保证在低硬件条件下能够正常运行。而dvm操作平台一般指明是ARM系统,所以采取的策略有所不同。需要注意的是Dalvik基于寄存器,但是这也是个映射关系,如果硬件没有足够的寄存器,Dalvik将多出来的寄存器映射到内存中。

4. JIT编译器。

Dalvik虚拟机可以看做是一个Java VM(虚拟机), Android系统初期,每次运行程序的时候,Dalvik负责将dex翻译为机器码交由系统调用。这样有一个缺陷:每次执行代码,都需要Dalvik将dex代码翻译为微处理器指令,然后交给系统处理,这样效率不高。为了解决上述问题,Google在Android2.2版本添加了JIT编译器。

JIT编译器的作用是:当App运行时,每当遇到一个新类,JIT编译器就会对这个类进行编译,经过编译后的代码,会被优化成相当精简的原生型指令码(即native code),这样在下次执行到相同逻辑的时候,速度就会更快。



当然使用JIT也不一定加快执行速度,如果大部分代码的执行次数很少,那么编译花费的时间不一定少于执行dex的时间。Google当然也知道这一点,所以JIT不对所有dex代码进行编译,而是只编译执行次数较多的dex为本地机器码。有一点需要注意,那就是dex字节码翻译成本地机器码是发生在应用程序的运行过程中的,并且应用程序每一次重新运行的时候,都要做重做这个翻译工作,所以这个工作并不是一劳永逸,每次重新打开App,都需要JIT编译。JIT 编译器可以对执行次数频繁的 dex/odex 代码进行编译与优化,将 dex/odex 中的 Dalvik Code(Smali 指令集)翻译成相当精简的 Native Code 去执行

5. JIT缺点。

  • 每次启动应用都需要重新编译(没有缓存)。
  • 运行时比较耗电,耗电量大。

三. ART虚拟机

1. ART和AOT。

JIT是运行时编译,是动态编译,可以对执行次数频繁的dex代码进行编译和优化,减少以后使用时的翻译时间,虽然可以加快Dalvik运行速度,但是有一个很大的问题:将dex翻译为本地机器码也要占用时间,这会拖慢应用的运行效率。 所以Google在4.4推出了全新的虚拟机运行环境ART(Android RunTime),用来替换Dalvik(4.4上ART和Dalvik共存,用户可以手动选择,5.0 后Dalvik被替换)。在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。这个过程叫做预编译AOT(Ahead-Of-Time)。这样,应用的启动(首次)和执行都会变得更加快速。

ART虚拟机直接执行本地机器码;而Dalvik虚拟机运行的是DEX字节码需要通过解释器执行。安卓运行时从Dalvik虚拟机替换成ART虚拟机,并不要求开发者重新将自己的应用直接编译成目标机器码,应用程序仍然是一个包含dex字节码的apk文件,这主要得益于AOT技术,AOT(Ahead Of Time)是相对JIT(Just In Time)而言的;也就是在APK运行之前,就对其包含的Dex字节码进行翻译,得到对应的本地机器指令,于是就可以在运行时直接执行了。ART应用安装的时候把dex中的字节码将被编译成本地机器码,之后每次打开应用,执行的都是本地机器码。去除了运行时的解释执行,效率更高,启动更快。

2. ART缺点:

  • 应用安装需要更长的时间,因为 DEX 字节码需要在安装时就翻译成机器码。
  • 由于在安装时时生成的 native 机器码是存储在内部存储器上,所以需要更多的内部存储空间。

3. JIT和AOT共存:

由于Art虚拟机有上述的缺点,所以在Android 7.0/7.1的ART引入了全新的Hybrid模式(JIT + AOT)

  • app在安装的时候dex不会再被编译, 所以安装速度快。

  • 应用在运行时 dex 文件先通过解析器(Interpreter)后会被直接执行(这一步骤跟 Android 2.2 - Android 4.4之前的行为一致),与此同时,热点函数(Hot Code)会被识别并被 JIT 编译后存储在 jit code cache 中并生成 profile 文件以记录热点函数的信息。

  • 手机进入 IDLE(空闲) 或者 Charging(充电) 状态的时候,系统会每隔一段时间扫描App目录下profile文件,并执行AOT编译(Google官方称之为profile-guided compilation)。

优点:
App安装速度快,占用存储少(只编译热点函数)。
缺点:
前几次运行会较慢, 只有用户操作得次数越多,jit 和AOT编译后, 性能才会跟上来。

三. 总结

找到一张图,一切尽在不言中.


参考资料:
Android学习笔记——虚拟机
JVM原理最全、清晰、通俗讲解

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

推荐阅读更多精彩内容