DVM与JVM的区别
- JVM基于栈,DVM基于寄存器
寄存器是 CPU 上面的一块存储空间,栈是内存上面的一段连续的存储空间。
- DVM 执行的 .dex 文件,JVM 执行 .class 文件。
- DVM:允许运行多个虚拟机实例,每一个应用启动都运行一个单独的虚拟机,并且运行在一个独立的进程中JVM:只能运行一个实例,也就是所有应用都运行在同一个 JVM 中
Davilk虚拟机
JIT
JIT(Just In Time Compiler, 即时编译),Android 2.2 版本提出的
JIT 模式的缺点:
- 每次启动应用都需要重新编译
- 运行时比较耗电,造成电池额外的开销
系统编译中控制JIT的位置
/build/target/product/runtime_libart.mk
PRODUCT_DEFAULT_PROPERTY_OVERRIDES += \
dalvik.vm.image-dex2oat-Xms=64m \
dalvik.vm.image-dex2oat-Xmx=64m \
dalvik.vm.dex2oat-Xms=64m \
dalvik.vm.dex2oat-Xmx=512m \
ro.dalvik.vm.native.bridge=0 \
dalvik.vm.usejit=true \
dalvik.vm.usejitprofiles=true \
JIT 虚拟机执行的本地机器码:
.java –> java bytecode(.class) –> dalvik bytecode(.dex) –> optimized dalvik bytecode(.odex)
- DEX means Dalvik EXcutable file.
- ODEX means Optimized Dalvik EXcutable file.
ART虚拟机
ART 即 Android Runtime。在 ART 环境中,应用在第一次安装的时候,字节码就会预先编译成机器码,使其成为真正的本地应用。这个过程叫做预编译( AOT, Ahead-Of-Time )
ART 虚拟机执行的本地机器码:
.java –> java bytecode(.class) –> dalvik bytecode(.dex) –> optimized android runtime machine code(.oat)
ART 对 Garbage Collection(GC)过程的改进:
- 只有一次 GC 暂停(Dalvik 需要两次)
- 在 GC 保持暂停状态期间并行处理
- 在清理最近分配的短时对象这种特殊情况中,回收器的总 GC 时间更短 优化了垃圾回收的工效,能够更加及时地进行并行垃圾回收,这使得 GC_FOR_ALLOC 事件在典型用例中极为罕见
- 压缩 GC 以减少后台内存使用和碎片
AOT 模式解决了应用启动和运行速度和耗电问题的同时也带来了另外两个问题:
- 应用安装和系统升级之后的应用优化比较耗时
- 优化后的文件会占用额外的存储空间
AOT 和 JIT 的不同
JIT 是在运行时进行编译,是动态编译,并且每次运行程序的时候都需要对 odex 重新进行编译;而 AOT 是静态编译,应用在安装的时候会启动 dex2oat 过程把 dex 预编译成 ELF 文件,每次运行程序的时候不用重新编译,是真正意义上的本地应用
dexopt 与 dex2oat 区别
-
dexopt 是对 dex 文件 进行 verification 和 optimization 的操作,其对 dex 文件的优化结果变成了 odex 文件,这个文件和 dex 文件很像,只是使用了一些优化操作码(譬如优化调用虚拟指令等)。
-
dex2oat 是对 dex 文件的 AOT 提前编译操作,其需要一个 dex 文件,然后对其进行编译,结果是一个本地可执行的 ELF 文件,可以直接被本地处理器执行。
dexopt was used to optimize DEX to ODEX (optimized DEX) which contains the optimized bytecode.
With AOT, dex2oat is used to optimize and compile DEX into an OAT file which may contain machine code in the ELF format.
Android系统对预编译的处理
-
编译的时候针对user版本会对apk进行处理,将里面的class.dex文件拿出来单独处理为odex,apk文件中只留下一些资源文件
-
第一次开机耗时会比较长,中间有大量的dex2oat的log存在,也是针对每个APK在做dex优化
LOCAL_DEX_PREOPT
这个变量设置为false可以使整个系统使用提前优化的时候,某个app不使用提前优化。在Android.mk中给该变量赋值为false,则编译生成的文件没有oat文件,也就意味着没有被提前优化。
Android 7.0 AOT/JIT 混合编译模式
混合编译模式的特点是:
- 应用在安装的时候 dex 不会被编译
- 应用在运行时 dex 文件先通过解析器(Interpreter)后会被直接执行(这一步骤跟 Android 2.2 - Android 4.4之前的行为一致),与此同时,热点函数(Hot Code)会被识别并被 JIT 编译后存储在 jit code cache 中并生成 profile 文件以记录热点函数的信息。
- 手机进入 IDLE(空闲) 或者 Charging(充电) 状态的时候,系统会扫描 App 目录下的 profile 文件并执行 AOT 过程进行编译。
Android 8.0
Android O 版本中,将会生成以下文件:
- .vdex:其中包含 APK 的未压缩 DEX 代码,以及一些旨在加快验证速度的元数据。
- .odex:其中包含 APK 中已经过 AOT 编译的方法代码。
- .art (optional):其中包含 APK 中列出的某些字符串和类的 ART 内部表示,用于加快应用启动速度。
Dalvik Optimization and Verification With dexopt