Android虚拟机和类加载机制

一、Android虚拟机

1.虚拟机的作用

虚拟机的作用就是给我们的代码提供运行时环境。

什么是运行时?
简单来说,运行时就是一个供操作系统使用的系统,它负责将你用高级语言(比如 Java)编写的代码转换成 CPU/处理器能够理解的机器码。

运行时由你的程序运行时所执行的指令构成,尽管本质上它们不属于程序代码的任何一部分。

CPU (或者更通用的说法电脑)只能够理解机器语言(二进制代码),所以为了使程序能够在 CPU 上运行,就必须将它们翻译成机器码,这一工作由翻译器完成。

2.dalvik虚拟机

DVM是Dalvik Virtual Machine的缩写,是Android4.4及以前使用的虚拟机,所有android程序都运行在android系统进程里,每个进程对应着一个Dalvik虚拟机实例。JVM和DVM都提供了对象生命周期管理,堆栈管理,线程管理,安全和异常管理及垃圾回收等重要功能,各自拥有一套完整的指令系统。
       APK在打包的过程中会先将java等源码通过javac编译成.class文件,然后通过android的dx工具将.class文件转换成Dalvik虚拟机能够执行的.dex文件。Dalvik虚拟机在应用程序启动时,会将.dex文件转换成快速运行的机器码进行执行。

3.ART ——Android runtime

在android5.0及后续版本中,Google采用了ART正式取代了以往的Dalvik虚拟机,ART虚拟机会将.dex文件转化为可直接运行的.oat机器码文件。

4.AOT

AOT指的是预编译技术,其全称为Ahead Of Time。AOT就是在我们安装APK时就将dex文件直接处理成可直接供ART虚拟机使用的机器码。

ART 内置了一个 Ahead-of-Time 编译器。在应用的安装期间,他就将 DEX 字节码翻译成机器码并存储在设备的存储器上。这个过程只在将应用安装到设备上时发生。由于不再需要 JIT 编译,代码的执行速度要快得多。

由于 ART 直接运行的是应用的机器码(native execution),它所占用的 CPU 资源要少于 使用 JIT 编译的 Dalvik。由于占用较少的 CPU 资源也就消耗更少的电池资源。

ART 和 Dalvik 一样使用的是相同的 DEX 字节码。编译好的应用如果使用 ART 在安装时需要额外的时间用于编译,同时还需要更多的空间用于存储编译后的代码,因为在安装的时候需要的时间过长所以在Android 7.0采用了AOT和JIT混合技术,在第一次安装的时候先不进行AOT,这时如果使用就先用JIT,当手机闲暇的时候,开启一个进程专门进行AOT把.dex编译成机器码。

5.JIT

JIT是Just In Time缩写,称为及时编译技术。以JVM为例,javac将源程序编译成java字节码,JVM通过逐条解释将字节码翻译成对应的机器指令,逐条读入,逐条解释翻译,执行速度必然比c/c++编译后的可执行二进制字节码程序慢,为了提高执行速度,就引入了JIT技术,JIT会在运行时分析应用程序代码,识别哪些方法可以归类为热方法,这些方法会被JIT编译器编译成对应的汇编代码,然后存储到代码缓存中,以后调用这些方法时就不用解释执行了,可以直接使用代码缓存中已编译好的汇编代码,这能显著提升应用程序的执行效率。Dalvik虚拟机在android2..2中增加了JIT,在Android 5.0时舍弃了JIT,因为Android 5.0采取了AOT技术,之后因为在安装的时候采用AOT技术使得安装时间过长,所以在Android 7.0的时候采用了JIT和AOT混合技术

6.Android对apk的执行流程

Java文件通过javac编译成.class文件,然后通过SDK中的dx工具将.class文件转换成Dalvik虚拟机能够执行的.dex文件,然后与Native code(JNI)和资源文件一起打包成apk,apk安装到手机后解压出.dex文件,Dalvik虚拟机会通过dexopt工具将.dex文件优化,形成Odex文件,ART则会将.dex文件通过dex2oat工具编译得到一个ELF文件,这是一个可执行文件。

二、分析对比

1.JVM和DVM对比

(1).Java虚拟机运行的是java字节码,Dalvik虚拟机运行的是Dalvik字节码

java程序经过编译,生成java字节码保存在.class文件中,JVM通过解码.class文件中的内容来运行程序。而DVM运行的是Dalvik字节码,所有的Dalvik字节码都是由Java字节码转换而来,并打包到.dex(Dalvik Executable)可执行文件中,DVM通过解释.dex文件来执行这些字节码。

(2).Dalvik可执行文件体积更小     

  android SDK中有个dx工具,该工具负责将Java字节码转换为Dalvik字节码,dx工具对Java类文件重新排列,将所有Java类文件中的常量池分解,消除其中冗余信息,重新组合形成一个常量池,所有的类文件共享同一个常量池,使得相同的字符串、常量在DEX文件中只出现一次,从而减少了文件的体积。

(3).JVM基于栈,DVM基于寄存器

关于栈式虚拟机:

1).代码必须使用这些指令来移动变量(即push和pop)

2).代码尺寸小和解码效率会更高些

3).堆栈虚拟机指令有隐含的操作数。

关于寄存器式虚拟机: 

1).使用堆栈来分配激活记录器

2).基于寄存器代码免去了使用push和pop命令的麻烦,减少了每个函数的指令总数。

3).代码尺寸和解码效率不如基于栈虚拟机,因为它包含操作数,所以指令大于基于堆栈的指令但是基于寄存器产生更少的代码,所以总的代码数不会增加。

4).寄存器虚拟机必须从操作指令中解码操作数,需要额外的解码操作。

因而,笼统说可以有以下结论:

1).要追求尽量实现简单:选择基于栈

2).传输代码的大小尽量小:选择基于栈

3).纯解释执行的解释器的速度:选择基于寄存器

4).带有JIT编译器的执行引擎的速度:随便,两者一样;对简易JIT编译器而言基于栈的指令集可能反而更便于生成更快的代码,而对比较优化的JIT编译器而言输入是基于栈还是基于寄存器都无所谓,经过parse之后就变得完全一样了。

2.DVM与ART对比

(1).ART采用AOT技术替代了JIT

      ART在应用程序安装时,就已经将所有的字节码编译成机器码,运行的时候直接运行的是机器码,剩下不太好翻译的代码,就在用户使用时再叫醒解释器来翻译。而Dalvik则是在运行应用程序运行时,实时地将字节码编译成机器码。因此,ART与Dalvik相比,省去了运行时将字节码编译成机器码的过程,极大地提升了应用程序的运行效率。

虽然运行效率得到提升,但同时带来了其它缺点:

1).安装时需要将字节码转换成机器码,因此ART需要更大的存储空间
2).安装时需要更多的时间

Dalvik虚拟机在启动的时候会先将.dex文件转换成快速运行的机器码,又因为65535这个问题,导致我们在应用冷启动的时候有一个合包的过程,最后导致的一个结果就是我们的app启动慢,这就是Dalvik虚拟机的JIT特性(Just In Time)。

 ART虚拟机是在Android5.0才开始使用的Android虚拟机,ART虚拟机必须要兼容Dalvik虚拟机的特性,但是ART有一个很好的特性AOT(ahead of time),这个特性就是我们在安装APK的时候就将dex直接处理成可直接供ART虚拟机使用的机器码,ART虚拟机将.dex文件转换成可直接运行的.oat文件,ART虚拟机天生支持多dex,所以也不会有一个合包的过程,所以ART虚拟机会很大的提升APP冷启动速度。

(2).提高了垃圾回收效率

        Dalvik虚拟机在GC时,会挂起虚拟机内部的所有线程,然后GC查找所有可回收的对象进行回收,回收后恢复所有挂起的线程。GC与应用程序的运行并不是并发执行的,如果GC频繁或者GC时间过长都会导致应用程序运行卡顿。
       ART对GC做了一定的改善,Dalvik的GC操作与应用程序是同步执行的(非并发),而ART则将原来的非并发过程改成部分并发,缩短了GC时间,提升了垃圾回收效率。

(3).提高了内存使用率、减少了内存碎片化

      Dalvik虚拟机垃圾回收采用了Mark and Sweep算法,即“标记-清除”算法,这种算法先对需要回收的内存区域进行标记,然后再统一清除,它是一种比较高效的算法,但是带来的弊端是会造成可用内存块的不连续,碎片化严重。虚拟机多次gc之后,本来连续的内存区域变得千疮百孔,以后为对象分配内存寻址会越来越难。
       而ART在内存分配上做了优化,比如它开辟了一块名为Large Object Space的内存区域,专门用来存放大对象,同时还引入了一个名为moving collector的技术,专门用来将gc后不连续的物理内存块对齐,解决了Dalvik上内存碎片化严重的问题。

Android 7.0(2016 年):采用混合编译机制,安装时先不编译中间代码,而是在用户空闲时将能够编译成机器码的那部分代码,通过 AOT 编译器先静态编译了。如果 AOT 还没来得及编译或者不能编译,再调用 JIT+ 解释器。这种机制,相当于用时间换空间,既缩短了用户安装 APP 的等待时间,又将虚拟机里编译器和解释器能做的优化提升到最大效率了。

三、Android的类加载机制

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值