.java .class .dex .apk
- .java 源文件
- .class 字节码文件 可以被jvm执行
- .dex Dalvik支持的字节码文件 可以被dalvik执行
- .apk 资源文件和dex文件打包后,再经过签名、对齐等操作变成apk文件(Android package)
apk安装流程
Dalvik、JIT 与 ART、AOT
Dalvik
通俗的讲,Dalvik虚拟机就是Android平台上的JVM虚拟机。主要对JVM的修改如下:
- 将原来 class 文件进行优化,例如将其中的常量冗余信息进行合并,提高虚拟机解析效率
- 修改 JVM 运行时基于栈的数据结构修改为 Dalvik 基于寄存器的数据结构,数据访问方式更快,运行效率更高
所以才会有了.dex文件格式,Dalvik将.apk文件解压(即安装apk的过程),转class.dex转换成ODEX文件(转换过程还会根据当前系统进行优化)存储在本地,运行APP的时候就是找到这个ODEX文件并通过Dalvik来执行。
JIT
JAVA是解释型语言,JVM执行字节码的时候通常有2个方案:
- 在执行前一次性把所有指令都编译成本地代码,然后再执行
- 逐条解释并执行
JIT是Just In Time,即时编译。在JVM解释执行字节码的时候,多次调用的程序段才被编译,编译后存放在内存中,下次直接执行编译后的本地代码。
当App运行时,每当遇到一个新类,JIT编译器就会对这个类进行编译,经过编译后的代码,会被优化成相当精简的原生型指令码(即native code)保存在内存中,下次遇到相同的逻辑的时候就更快了。但是如果大部分代码的执行次数很少,那么编译花费的时间不一定少于执行dex的时间。所以采用的是只编译执行次数较多的dex为本地机器码的做法。
至于为什么,是因为在运行时,Dalvik虚拟机会将dex代码翻译成处理器指令,然后交给系统处理,这样效率就很低。将字节码翻译成机器码也是需要时间的,如果大部分代码的执行次数很少,那么编译花费的时间不一定少于执行的时间。
就HotSpot虚拟机来说的话有client和server两种模式,又有一定程度的不同
使用AOT策略的ART虚拟机
JIT是运行时编译,这样可以对执行次数频繁的dex代码进行编译和优化,虽然可以加快Dalvik运行速度,但是还是有弊病,那就是将dex翻译为本地机器码也要占用时间,所以Google在4.4之后推出了ART,用来替换Dalvik(在5.0中彻底替换)。
ART的策略与Dalvik不同,在ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。之后打开App的时候,不需要额外的翻译工作,直接使用本地机器码运行,因此运行速度提高。这就是AOT,Ahead Of Time ,相应的会消耗掉更多的存储空间以及导致安装时间加长。