Jimmy Chen

A Programmer

(原创)基于Android R之了解下ArtField、ArtMethod、DexCache和Class

  在初略了解了ClassLinker之后,我们下一步先了解一些相关的类或者结构体。ArtField在ART虚拟机底层中用来表示类的成员变量的;ArtMethod则是用来表示类的成员方法;DexCache和Dex文件有关,用于换成Dex文件的信息;Class则是在ART虚拟机中表示类的信息。在开始前需要先了解相关类之间的关系,如下图(摘自《深入理解ART虚拟机一书》)

《(原创)基于Android R之了解下ArtField、ArtMethod、DexCache和Class》

其次,还需要再简单了解下Dex文件的格式,Dex文件的排列内容可以参考如下:

《(原创)基于Android R之了解下ArtField、ArtMethod、DexCache和Class》

Dex文件的各个节简单解释一下:

  • header:DEX 文件头,记录了一些当前文件的信息以及其他数据结构在文件中的偏移量
  • string_ids:字符串的偏移量
  • type_ids:成员变量、成员方法等的类型信息的偏移量
  • proto_ids:方法声明的偏移量
  • field_ids:字段信息的偏移量
  • method_ids:方法信息(所在类、方法声明、方法名)的偏移量
  • class_def:类信息的偏移量
  • data:数据区
  • link_data:静态链路数据区

上述的字段表示的都是一些偏移量数组,并未存储真是的数据,在解析Dex文件的时候是通过这些偏移量到data区进行查找。

了解一下ArtField

下面只列举一下相关内容

  如上所示,一个ArtField对象代表类中的一个成员变量。比如,一个Java类A中有一个名为a的long型变量。那么,在ART虚拟机中就有一个ArtField对象来表示这个a。但是从上面的定义中我们可以了解到,ArtField中是没有表示这个long型变量的成员变量的,而且对应的setter或者getter方法获取或者设置的都是Ptr指针。所以ArtField对应仅仅只是用来表示一个Java类的成员变量,但是它自己并不提供内存空间来存储这个Java成员变量的内容。

了解一下ArtMethod

下面列举了一部分ArtMethod类的内容,省略了大部分内容,为了篇幅,省略号也不留了,省略掉省略号

一个ArtMethod代表一个Java类中的成员方法。对一个方法而言,它的入口函数地址是最核心的信息。

了解一下DexCache

  • Dex文件按照自己的格式存储将不同的信息分别存储,比如type_ids、string_ids、field_ids和method_ids等
  • Dex文件里大部分都是借助symbol reference来间接获取目标信息。相反,DexCache则是直接包含最终的目标信息。比如,dex文件的type_ids数组里保存的实际上是该dex文件里用到的或者自定义的数据类型所对应名称在string_ids数组里的索引,而DexCache resolved_types包含的则是一个GcRoot<Class>*数组,它存储的内容直接指向dex文件里用到的或自定义数据类型所定义的Class对象。由于从symbol reference到最终的信息需要经过一个解析的过程,所以上面DexCache的那几个成员变量命名中都有resolved_的前缀。

了解一下Class

Art虚拟机中使用的class类,我们和DexCache一样,只关注其中的成员变量,至于对成员变量的操作方法,我们后面遇到再看

上述Class的成员变量比较多,如下几个成员变量尤其值得读者关注。我们先介绍他们的情况

  • iftable_:保存了该类所有直接实现或者间接实现的接口信息。直接实现是指该类自己implements的某个接口。间接实现是指它的继承关系上有某个祖父类implements了某个接口。另外,一条接口信息包含两个部分,第一个部分是接口类所对应的Class对象,第二部分则是该接口类中的接口方法
  • vtable_:和iftable_类似,它保存了该类所有直接定义或间接定义的virtual方法信息。比如,Object类中有耳熟能详的wait、notify、toString等的11个virtual方法。所以任意一个派生类中都包含这11个方法
  • methods_:methods_指包含本类直接定义的direct方法、virtual方法和那些拷贝过来的诸如Miranda这样的方法。一般而言,vtable_包含的内容要远多于methods_
  • embedded_imtable_、embedded_vtable_和fields_为隐含成员变量。其中,前两个变量只能实例化的类中才存在。实例化是指该类在Java层的对应类可以通过new来创建一个对象。举个反例,基础数据类、抽象类、接口类就属于不能实例化的类

OK,这篇就简单了解下ArtField、ArtMethod、DexCache和Class类相关的内容。

发表回复

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