Android 虚拟机方面的知识,我是通过《深入理解 Android 内核设计思想》来学习的,内容特别多(只有一章,但有 160 页),感觉和 Android 开发有些偏,因此很多内容都没有认真去看,比如 EFL 格式等,这里只是选取了一些感觉比较重要的做一个大致的简单的介绍。
虚拟机基础知识
Java VM
详见《深入理解 Java 虚拟机》
LLVM
LLVM 全称是 Low Level Virtual Machine,但和虚拟机没太大关系,官方定义是:The LLVM Project is a colection of modular and resuable compiler and toolchain technologies。即 LLVM 的价值在于可模块化、可重复使用。
LLVM 框架如下所示:
Frontend:负责分析源代码、检查错误,然后将源码编译成抽象语法树
Optimizer:通过多种优化手段来提高代码的运行效率,在一定程度上独立于具体的语言和目标平台
Backend:也被称为代码生成器,用于将前述的源码转化为目标前台的指令集
LLVM 的模块化:
可以看出,如果要让基于 LLVM 框架的编译器支持一种新语言,那么所要做的可能仅仅是实现一个新的 Frontend,而已有的 Optimizer 和 Backend 则能做到重复使用。上述能力得到实现的关键在于 LLVM 的 Intermediate Representation(IR),IR 能在 LLVM 的编译器中(具体在 Optimizer 阶段)以一种相对独立的方式来表述各种源代码,从而很好地剥离了各种不同语言间的差异,进而实现模块的复用。
LLVM 和 Android 的关系可以参考 RednaxelaFX 大神的一个回答:Android 中的 LLVM 主要做什么?
简单来说,就是从 Jellybean MR1 版本开始,Google 将 LLVM 作为 Android 工具链和 Android NDK 的替代编译器,可以用于编译在 Android 应用程序中的 C/C++ 代码。
Android 中的经典垃圾回收算法
Android 中不管是 Dalvik 还是 Art,它们所使用的垃圾回收算法都是基于 Mark-Sweep 的。
GC 的触发时机有:
-
GC_FOR_MALLOC。堆内存已满的情况下程序尝试去分配新的内存块
-
GC_CONCURRENT,堆内存超过特定阈值,触发并行的 GC 事件
-
GC_HPROF_DUMP_HEAP,开发者主动请求创建 HPROF
-
GC_EXPLICIT,程序主动调用 gc() 函数,尽量避免这种用法
Art 和 Dalvik 之争
Dalvik 是 Android 4.4 之前的标准虚拟机,为了性能上的考虑,Dalvik 所做出的努力有:
-
多个 Class 文件融合进一个 Dex 文件中,以节省内存空间
-
Dex 文件可以在多个进程之间共享
-
在应用程序运行之前完成字节码的检验操作,因为检验操作十分耗时
-
优化字节码
-
多个进程共享的代码不能随意编辑,这是为了保证安全性
但 Android 从诞生起就背负了“系统庞大,运行慢”的包袱,因此,从 Android 4.4 开始,Art 就以和 Dalvik 暂时共存的形式正式进入了人们的视野,而在 Android Lollipop 中正式取代了 Dalvik 的位置。
Art 相比 Dalvik 在性能上有着显著的优势,主要原因在于 Dalvik 虚拟机多数情况下还得通过解释器的方式来执行 Dex 数据(JIT 虽然能在一定程度上提高效率,但也仅仅是针对一小部分情况,作用有限);而 Art 虚拟机则采用了 AOT(Ahead Of Ti