Jimmy Chen

A Programmer

原创)基于Android R之ClassLinker分析

  ART虚拟机系列,在前几篇我们分析了ART虚拟机的创建、JavaVmExt和JNIEnvExt。这篇我们继续展开,我们来分析下ART虚拟机中ClassLinker的作用。首先我们看下ClassLinker初始化的地方

ClassLinker的整个初始化过程都是在Runtime::Init中进行的,我们分两部分进行

1. ClassLinker构造函数

  • ClassTable用于记录ClaaLoader中已经加载的类
  • 上述代码中,kFindArrayCacheSize大小为16,
  • find_array_class_cache_GcRoot<mirror::Class>类型的对象,大小也为kFindArrayCacheSize
  • 上述代码中,带有很多trampoline一词的成员变量,这些成员变量是一些函数指针,这些函数指针是用于做函数跳转的。因为ART虚拟机即支持从运行dex中的代码,也支持运行oat中的二进制代码。从dex跳转到oat或者从oat跳转到dex之类的控制就和这些trampoline函数有关
  • class_roots_成员变量的类型是GcRoot<mirror::ObjectArray<mirror::Class>>,借助GcRoot的封装,它实际保存的信息是一个ObjectArray对象,数组中的元素类型则是mirror::Class类型

2. InitFromBootImage方法分析

2.1 GetImageRoot方法分析下

对上面的内容进行一个总结:

  • ImageHeaderGetImageRoot返回的是mirror::Object*指针,但它实际上是一个Object Array<mirror::Class>对象。所以,InitFromBootImage第一部分的最后通过down_cast宏将其向下转换成了子类类型的对象。最后再构造一个GcRoot对象赋值给class_roots_。
  • 而这个数组的内容又是来自于art文件的image_roots_所在的地方。也就说,class_roots_的内容保存在art文件的image_roots_所在的区域。

如下图(来自《深入理解ART虚拟机》一书)进一步展示了上述内容。

《原创)基于Android R之ClassLinker分析》

  • 左边是一个art文件,它会被映射到虚拟机进程,相关信息都是从这块内存中读取的。ImageHeader是art文件的头部信息。image_roots_是ImageHeader中的成员变量。在代码中,它的数据类型是uint32_t,其含义有两种解读方法:对映射到内存里的art文件来说,image_roots_指向某个内存地址;对文件来说,它指向art文件中的某个位置。
  • 我们更需要关注这块位置中存储的信息是什么。由上面代码内容可知,image_roots_所指向的那块区域存储的是一个ObjectArray<Object>数组。这个数组里有两个元素,其索引位置由ImageRoot枚举来描述,其中kDexCaches取值为0,kImageRoots取值为1。
  • 继续来看这个ObjectArray<Object>。虽然其模板参数的类型是Object。但对kImageRoots而言,这个Object其实又是一个ObjectArray<Class>数组。即kImageRoots元素本身又是一个数组,这个数组里元素的类型是Class。

所以,简单来说,ImageHeader的image_roots_所指向的那块区域包含两组信息:

  • 第一个是ObjectArray<DexCache>数组。
  • 第二个是ObjectArray<Class>数组。

2.2 AddImageSpace方法分析

关于ClassLinker的内容就到这里了,ClassLinker的内容着实博主也是刚刚开始了解,权当自己的学习记录了,可能就没有输出太多的个人见解了。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注