Android JVM,Dalvik,ART虚拟机

一.java平台的虚拟机Jvm.

1.jvm的作用

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

Android JVM,Dalvik,ART虚拟机_第1张图片
java流程

2.jvm分析

jvm相关知识体系过于庞大,有兴趣可以看:
JVM原理最全、清晰、通俗讲解

一.Android平台的虚拟机.

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

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

2.Android平台Dalvik的特点。

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

3.jvm和Dalvik的区别。

  1. JVM是基于栈,Dalvik指令集是基于寄存器的架构,
  2. JVM 可以执行的文件是 .class 结尾的字节码文件,而 Dalvik 执行的是 dex 文件。


    Android JVM,Dalvik,ART虚拟机_第2张图片
    image.png

4.JIT编译器。

Dalvik虚拟机可以看做是一个Java VM(虚拟机),他负责将.dex文件解释为机器码,如果不做处理的话,每次执行代码,都需要Dalvik将dex代码翻译为微处理器指令,然后交给系统处理,这样效率不高。为了解决上述问题,Google在Android2.2版本添加了JIT编译器。
JIT编译器的作用是:当App运行时,每当遇到一个新类,JIT编译器就会对这个类进行编译,经过编译后的代码,会被优化成相当精简的原生型指令码(即native code),这样在下次执行到相同逻辑的时候,速度就会更快。


Android JVM,Dalvik,ART虚拟机_第3张图片
image.png

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

5.JIT缺点。

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

6.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)。这样的话,应用的启动(首次)和执行都会变得更加快速。

7.ART缺点:

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

8.JIT和AOT共存:

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

  1. app在安装的时候dex不会再被编译, 所以安装速度快
  2. App运行时,dex文件先通过解析器被直接执行,热点函数会被识别并被JIT编译后存储在 jit code cache 中并生成profile文件以记录热点函数的信息。
  3. 手机进入 IDLE(空闲) 或者 Charging(充电) 状态的时候,系统会每隔一段时间扫描App目录下profile文件,并执行AOT编译(Google官方称之为profile-guided compilation)。
    优点: App安装速度快,占用存储少(只编译热点函数)。
    缺点: 前几次运行会较慢, 只有用户操作得次数越多,jit 和AOT编译后, 性能才会跟上来。

三.总结.

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


Android JVM,Dalvik,ART虚拟机_第4张图片
image.png

参考资料:
Android学习笔记——虚拟机

你可能感兴趣的:(Android JVM,Dalvik,ART虚拟机)