ART深入浅出3--了解Boot.art和boot-*.art

本文深入探讨Android 7.1系统中boot.art的加载过程和文件格式,详细介绍了ImageSpace的初始化、ImageHeader的解析以及boot.art包含的DexCaches和ClassRoots等关键组件。内容涉及类对象映像、内存管理、预编译库的组织形式,阐述了Android系统如何在启动时加载并使用预加载类。
摘要由CSDN通过智能技术生成

本文基于Android 7.1,不过因为从BSP拿到的版本略有区别,所以本文提到的源码未必与读者找到的源码完全一致。本文在提供源码片断时,将按照 <源码相对android工程的路径>:<行号> <类名> <函数名> 的方式,如果行号对不上,请参考类名和函数名来找到对应的源码。

在Android7.0之前,所有bootclasspath指定的库会被同一编译成为boot.oat和boot.art两个文件。其中boot.oat包含了编译后的机器码指令,而boot.art文件,则是一个类对象映像。boot.art内包含了所有framework/base/preloaded-classes文件列出的所有类。这些类会被一次性的载入到内存中,并可以被直接使用。
在Android7.0及以后,boot.art和boot.oat被分成了以boot-<packagename>.oat/art方式的多个库。当有一个库被更新,不至于整个boot.art/boot.oat被更新。
当然,你有时也看不到这些被分开的boot.art/boot.oat库,这是因为,Android7.0可以通过参数来控制。
为了简便,我们只讨论所有bootclasspath包作成一个boot.art/boot.art的情况。
除此之外,如果在编译ROM时,选择打开ODEX,那么,编译程序就会生成boot.oat/boot.art,连同system/app, system/priv-app下面的程序,都会生成它们的oat文件。一般boot.oat/boot.art(可能是boot-.oat, boot- .art) 会放在 /system/framework/arm64 或者 /system/framework/arm下面。在系统初始化时,这些预编译好的oat/art文件会被拷贝到/data/dalvik-cache下面。在android7.0上,则会直接读取它们,不用再拷贝了。

boot.art文件的加载

为了探究boot.art文件的格式,我们首先要大致了解下它的加载过程。
boot.art文件是在创建heap的时候加载的。在构造函数Heap::Heap,我们可以看到如下的代码:
art/gc/heap.cc:278 Heap::Heap

  // Load image space(s).
  if (!image_file_name.empty()) {
   ....
    for (size_t index = 0; index < image_file_names.size(); ++index) {
      std::string& image_name = image_file_names[index];
      std::string error_msg;
      space::ImageSpace* boot_image_space = space::ImageSpace::CreateBootImage(
          image_name.c_str(),
          image_instruction_set,
          index > 0,
          &error_msg);
....
  }

我把其中很多代码都省略了,我们只看我们关心的代码space::ImageSpace::CreateBootImage 函数。
heap把内存分成了若干的space,每个space管理一大块内存,每个space下面都有自己的内存分配和回收算法,这样可以应对不同的内存需求。比如,有些内存一但分配,就不释放的,如为class,method, field这些元对象分配的内存;一些大内存对象,如图片的像素数组等,一个对象就占用很多内存;或者是那些频繁创建但是很快丢弃的对象。等等。
Boot.art内部保存的,主要是一些class,method,field,还有一些非常基础的类对象,比如用于管理dex数据的dexcache对象等,这些对象,一旦分配,就不会释放,不仅是在一个应用的生命周期,而是在整个系统的周期内。也就是说,只有手机关机了,它们才会被丢弃掉。故此,ART将这些数据做成映像,系统一启动就把它们载入到内存,而且是zygote进程的内存,这样所有zygote的子进程就可以直接享用这些数据了。
下面
art/runtime/gc/space/image_space.cc:1149 ImageSpace::Init

ImageSpace* ImageSpace::CreateBootImage(const char* image_location,
                                        const InstructionSet image_isa,
                                        bool secondary_image,
                                        std::string* error_msg) {
....
  bool found_image = FindImageFilename(image_location, image_isa, &system_filename,
                                       &has_system, &cache_filename, &dalvik_cache_exists,
                                       &has_cache, &is_global_cache);

....
  ImageSpace* space;
  bool relocate = Runtime::Current()->ShouldRelocate();
  bool can_compile = Runtime::Current()->IsImageDex2OatEnabled();
  if (found_ima
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值