一篇文章让你清楚DVM、JVM、ART、JIT、ODEX、VDEX、DEX、oat

DVM 和 JVM的区别

   1、DVM基于寄存器,JVM基于栈。  DVM效率要更高

      解释为什么寄存器效率更高?

      a、 因为寄存器是CPU中的一部分, 堆栈是内存的一种结构。 内存是CPU和硬盘之间的通道。 寄存器是CPU的储存器,速度快。

      b、  一个是直接对CPU进行操作,一个是对内存操作,然后在转化成CPU指令操作。所以寄存器效率更快。

2、DVM 运行dex  JVM运行java字节码


DVM 和 ART的区别

1、 Dalvik虚拟机 的编译模式是 JIT是,一种运行时编译, 每次在打开应用的时候都要重新去编译。

2、 ART   虚拟机  的编译模式是AOT,它是预编译,在应用安装的时候会启动 dex2oat过程,直接把dex编译为ELF文件,以后在执行APP的时候不用编译了,效率更高

      AOT 和 JIT 是对应的编译模式而已。

      优缺点:

      1、Dalvik 安装快,体积小,但是每次运行APP都要编译, 每次编译特别耗电

      2、ART安装慢,体积大,多余10%-20%,     但是每次运行APP直接读取本地机器码,效率快,不用每次编译 比较省电

     AOT编译时机

  1. 随Android ROM构建时一起编译

  2. 程序安装时进行编译(针对第三方应用)

发展史:

 Android 2.2  使用DVM虚拟机

 Android 4.4   推出ART虚拟机

 Android 5.0   全面替换ART

 Android7.0   仍是ART环境,但是编译策咯改为AOT 和 JIT 混合编译。 

  7.0 特点 :首次安装 不再统一执行dex2oat改由程序运行时根据实际情况来决定哪些部分被编译成本地代码,会采用JIT混合编译。然后在满足两个条件的时候在执行AOT优化。 

          条件: 系统同时满足idle和充电两个条件时唤醒,按照一定逻辑遍历执行程序的AOT优化

  7.0优点:集合了AOP和JIT的特点,使得安装速度,运行速度,储存空间和耗电等指标都得到了优化。


疑问?  什么是odex? vdex?  apk安装流程  怎么打包成一个apk  ART加载本地elf文件流程?    7.0JIT和AOT怎么互相配合的?  ART 相对于 DVM的提升?


odex、vdex、dex、art文件、oat

  

1、什么是dex文件

是java代码最终合成的文件,虚拟机直接执行的文件。但是系统做了一些优化,不直接从apk中提取dex运行启动apk,效率太慢,所以就有了后面的odex、oat文件。 都是通过dex来生成的。


1、什么是odex? (5.0之前)

5.0之前,在使用DVM虚拟机的时候,系统设计的文件,odex是由classess.dex生成的,即优化的过dex。

2、8.0之后的odex?怎么来的?

8.0之后,odex是从vdex中提取出来的一个可执行文件。这样vdex文件就减少了,  odex + vdex = apk全部源码。

3、odex怎么生成的?(5.0之前)

apk在安装的时候,就会验证和优化,验证代码合法性和代码执行速度。验证完毕后会产生odex。

4、odex的特点什么作用?:

      a、运行apk的时候,直接加载odex,避免重复验证和优化,加快了apk的响应时间,加快软件加载速度。(也就是网上好多都说的提前从dex提取出odex,其实是验证和优化这一步)

      b、防盗版,因为在安装apk的时候,系统会把apk压缩包里面的dex文件删除,并把apk文件存放到权限比较高的目录,一般用户拿不到,即使拿到也用不了,因为里面的dex文件已经被删除了。


1、oat文件是什么?(5.0及5.0之后)

5.0全面替换ART虚拟机,使用AOT编译模式,生成oat文件,是对ELF格式做的扩展的二进制可运行文件。

2、oat.ELF文件的特点

     a、比dex文件大10%-20%(因为它包括dex和本地代码机器指令)

     b、ART安装慢,体积大,多余10%-20%,     但是每次运行APP直接读取本地机器码,效率快,不用每次编译 比较省电

3、相比odex文件有什么优势?劣势?

 其实这个问题可以回放到上面的问题,AOT和JIT的编译的优缺点。


1、art文件是啥? 这个可不是ART虚拟机的意思。

      是odex进行优化生成的可执行二进制码文件

    a、 用于加快应用启动速度。

    b、 从odex中拆分出来的,art文件主要为了加快应用的对“热代码”的加载与缓存

    热代码是什么?  

    我自己的理解 7.0之后采用JIT和AOT混合编译,在第一次安装运行的时候,是直接采用JIT编译,产生的编译结果就叫做”热代码“,然后手机空闲了AOT在      编译这个热带码,编译在本地


1、vdex是什么?

google在android8.0新增加了vdex文件,通过package直接转化的可执行二进制文件。

2、vdex有什么特点?

     a、加快验证速度的元数据,在手机安装APK的时候,系统都会验证代码的合法性。(vdex会较快验证速度)

     b、有助于提升软件更新的性能和体验。(vdex会保存验证过的dex文件,以便在ART系统更新期间,无需再次解压验证dex)

     c、 默认是启动状态,停用该功能 请将 ART_ENABLE_VDEX 环境变量设为 false。



smali文件是什么?

虚拟机有自己的一套指令集,汇编语言,反编译dex文件就可以得到smali文件, smali文件就是寄存器语言!

DVM ==>  java ==>.class ==>.dex ==> odex  == >smali

ART  == >  java ==>.class ==>.dex ==> oat    == >smali 

总结:虚拟机是基于寄存器的,寄存器是CPU的储存器,寄存器如何运行,就是通过寄存器指令,寄存器指令就是smali语言,所以无论的dex,odex,vdex,oat他们只不过是对dex的优化,最终加载在虚拟机后,会转换成smali寄存器语言,去运行。


静态链接库和动态链接库

静态链接库

静态链接库的特点是会在程序的编译链接阶段就完成函数和变量的地址解析工作,并使之成为可执行程序中不可分割的一部分。

动态链接库

动态链接库不需要在编译时就打包到可执行程序中,而是等到后者在运行阶段在实现动态的加载和重定位。动态链接库在被加载到内存中之后,操作系统需要为它执行动态连接操作。

动态链接库的处理过程如下:

  1. 在编译阶段,程序经历了预编译、编译、汇编及链接操作后,最终形成一个 ELF 可执行程序。同时程序所依赖的动态库会被记录到 .dynamic 区段中;加载动态库所需的 Linker 由 .interp 来指示。

  2. 程序运行起来后,系统首先会通过 .interp 区段找到连接器的绝对路径,然后将控制权交给它

  3. Linker 负责解析 .dynamic 中的记录,得出程序依赖的所有动态链接库

  4. 动态链接库加载完成后,它们所包含的 export 函数在内存中的地址就可以确定下来了,Linker 通过预设机制(如 GOT)来保证程序中引用到外部函数的地方可以正常工作,即完成 Dynamic Relocation

发布了51 篇原创文章 · 获赞 78 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/weixin_39079048/article/details/99293958