ART虚拟机介绍

ART全称是Android Runtime,指的是为Android应用提供运行环境的虚拟机,所以叫ART虚拟机。ART最初是Dalvik虚拟机,从Android 4.4开始逐渐抛弃Dalvik虚拟机进行针对性优化、引入新的特性,渐渐脱离Dalvik成为独一无二的ART虚拟机。

ART整体架构

ART整体分为Compiler&Interpreter和Runtime两个部分,它们的具体内容如下:

  • Complier&Interpreter 负责对代码进行处理
    • 解释器,用于解释执行字节码
    • JIT Just-in-Time 即时编译,在运行过程中将执行频率较高的函数编译为机器指令,从而提升运行速度和性能
    • AOT Ahead-of-Time 预先编译,在运行开始前对部分代码进行预先编译,从而提升运行速度和性能
  • Runtime 提供对Java语言机制的支持
    • 内存管理
    • 线程
    • 异常
    • 类管理
    • JNI,Java Native Interface
    • 调试
    • ...

ART对象分配

在面向对象编程中,程序会创建许多个对象。在Android中,这些对象就需要由ART来分配合理的内存资源,在对象销毁时进行内存资源的回收和清理。

创建对象需要有类的定义,类定义决定着一个对象的大小(内存布局,比如类成员的大小和分布)和行为(函数信息)。在Java中,所有类都继承自Object类,在Object类中,有一个klass_成员负责该对象所属类的类对象,还有一个monitor_成员负责存储Hash Code和锁信息。

类管理

对于某个类的一个对象,它分配到的空间取决于继承链,继承链上的所有成员都会被分配空间。在Java中,当类第一次被使用时,将会进行该类的加载。

内存分配

Android应用的内存分配是由ART虚拟机来处理的,也就是说应用的内存申请并不是向操作系统提出,而是向虚拟机提出,虚拟机则负责对OS内存的占用和布局。如下所示,

1
2
3
4
5
6
7
8
9
--------------------------------------
APP
--------------------------------------
----------------------- -------------
ART VM Heap Native Heap
----------------------- -------------
--------------------------------------
Linux Kernel 内存管理
--------------------------------------

ART虚拟机使用不同的分配器来分配内存,对于不同的内存申请使用合适的内存分配器。ART的内存分配器有以下几种:

  • TLAB
    • 相当于局部Cache,分配速度快,但是体积小
  • ROSallocator
    • 内存体积中等,从VM mem pool中分配内存
  • LOSallocator
    • 申请的内存体积较大,虚拟机将向Linux系统申请内存并分配

内存回收

当对象不再被使用时,自然需要销毁对象,回收分配给它的内存资源,这就是内存回收。常见的内存回收机制有两种:GC和RC。

  • GC机制全称Garbage Collection(垃圾回收),这种机制的做法是定期(或者根据某些条件)查找系统中不用的对象并释放内存。
  • RC机制全称Reference Counting(引用计数),这种机制与GC不同,它对每一个对象进行引用计数,当计数为0时说明不再有引用者使用该对象,于是销毁对象释放内存。

Android系统采用GC机制进行内存回收,而IOS的Swift采用RC机制进行内存回收。两种方式各有优劣,GC机制因为不能及时回收内存,所以应用的内存占用较大;而RC机制则无法直接回收两个相互引用(或者多个对象形成环引用)但是无用的对象的内存。

在ART的内存回收机制中,对象的引用被分为强引用、软引用和弱引用。强引用不会被回收,软引用会在内存不足时被回收,而弱引用在GC被触发时就会被回收。GC的触发策略不同固件厂商各不相同,通常来说包括内存不足、VM占用内存到达某个警戒值或者其他条件(比如锁屏若干时间后触发GC回收内存)。

要进行GC,就要确定对象是否可以被回收,于是这里引入GC roots的概念。GC roots是指一些特殊的栈、引用或者静态变量,在GC时从这些roots出发进行遍历,并把所有遍历到的对象打上标记(mark),遍历完成后所有未被mark的对象就是孤立对象,这些无用的对象将会被回收。在进行内存回收时,有两种做法:

  • Tracing GC 直接将所有未被mark的对象的内存
  • Coping GC 这里先介绍一下内存碎片:因为各个应用每次申请的内存总是大小不一,所以久而久之会产生了内存碎片化问题,也就是有许多小的空闲内存块,但是缺少较大的完整内存块,从而难以满足较大体积的内存需求。Coping GC将mark过的对象拷贝集中到一个区域,然后释放之前的整块内存空间,从而消除了一部分内存碎片

在ART的内存回收策略中,前台GC(对前台应用进行的GC)采用Tracing GC的方式进行,以避免影响应用使用;后台GC(对后台进程,例如Service,进行的GC)采用Coping GC的方式,以避免内存碎片产生。

ART执行方式

在ART虚拟机,代码有三种执行方式,分别是:

  • 解释执行,解释执行字节码
  • JIT,在解释执行同时对函数进行打分,分数高(取决于打分策略)的函数将被编译为机器指令,从而提高之后执行该函数的速度
  • AOT,以dex为单位进行预先编译,并将编译后的机器指令持久化存储下来,每次执行到相应部分时直接执行机器指令而无需解释执行字节码

ART栈管理

对于解释执行的部分,栈托管到虚拟机完成;对于编译过的部分,栈管理与native代码一致,遵循对应指令集的压栈约定。

对于解释执行和编译执行的切换,ART采用trampoline-bridge机制来进行。


ART虚拟机介绍
https://young-cloud-creator.github.io/art-basic/
作者
Young Cloud Creator
发布于
2022年8月18日
许可协议