Android6.0中 java堆的创建

主要参考:http://blog.csdn.net/luoshengyang/article/details/42379729 罗老师的 《ART运行时Java堆创建过程分析 》一文,将其中安卓4.4的代码和具体实现替换成Android6.0

//art/runtime/runtime.cc
 782 bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) {
    ...
 788   using Opt = RuntimeArgumentMap;//即Opt是RuntimeArgumentMap的别名
 789   RuntimeArgumentMap runtime_options;//RuntimeArgumentMap是一个key->value map
     ...
 849   XGcOption xgc_option = runtime_options.GetOrDefault(Opt::GcOption);
 850   ATRACE_BEGIN("CreateHeap");
 851   heap_ = new gc::Heap(runtime_options.GetOrDefault(Opt::MemoryInitialSize),
     //gc::Heap::kDefaultInitialSize 堆的初始大小,由-Xms指定
 852                        runtime_options.GetOrDefault(Opt::HeapGrowthLimit),
     //Default is 0 for unlimited,堆允许增长的上限值,这是堆的一个软上限值,通过选项-XX:HeapGrowthLimit指定
 853                        runtime_options.GetOrDefault(Opt::HeapMinFree),
     //gc::Heap::kDefaultMinFree,堆的最小空闲值,通过选项-XX:HeapMinFree指定。
 854                        runtime_options.GetOrDefault(Opt::HeapMaxFree),
     //gc::Heap::kDefaultMaxFree,堆的最大空闲值,通过选项-XX:HeapMaxFree指定。
 855                        runtime_options.GetOrDefault(Opt::HeapTargetUtilization),
     //gc::Heap::kDefaultTargetUtilization
 856                        runtime_options.GetOrDefault(Opt::ForegroundHeapGrowthMultiplier),
     //gc::Heap::kDefaultHeapGrowthMultiplier
 857                        runtime_options.GetOrDefault(Opt::MemoryMaximumSize),
     //gc::Heap::kDefaultMaximumSize,由-Xmx指定
 858                        runtime_options.GetOrDefault(Opt::NonMovingSpaceCapacity),
     //gc::Heap::kDefaultNonMovingSpaceCapacity
 859                        runtime_options.GetOrDefault(Opt::Image),
     //用来创建Image Space的Image文件,通过选项-Ximage指定。
 860                        runtime_options.GetOrDefault(Opt::ImageInstructionSet),
     //kRuntimeISA
 861                        xgc_option.collector_type_,
 862                        runtime_options.GetOrDefault(Opt::BackgroundGc),
     //类型为BackgroundGcOption
 863                        runtime_options.GetOrDefault(Opt::LargeObjectSpace),
     // gc::Heap::kDefaultLargeObjectSpaceType,类型为gc::space::LargeObjectSpaceType
 864                        runtime_options.GetOrDefault(Opt::LargeObjectThreshold),
     //gc::Heap::kDefaultLargeObjectThreshold,类型为Memory<1>
 865                        runtime_options.GetOrDefault(Opt::ParallelGCThreads),
     //0u ,类型为unsigned int。GC暂停阶段用于同时执行GC任务的线程数,通过选项-XX:ParallelGCThreads指定。
 866                        runtime_options.GetOrDefault(Opt::ConcGCThreads),
     //类型为unsigned int。GC非暂停阶段用于同时执行GC任务的线程数,通过选项-XX:ConcGCThreads指定。
 867                        runtime_options.Exists(Opt::LowMemoryMode),
     //是否在低内存模式运行,通过选项XX:LowMemoryMode指定。
 868                        runtime_options.GetOrDefault(Opt::LongPauseLogThreshold),
     //GC造成应用程序暂停的时间阀值,一旦超过该阀值,则输出警告日志,通过选项XX:LongPauseLogThreshold指定。
 869                        runtime_options.GetOrDefault(Opt::LongGCLogThreshold),
     //GC时间阀值,一旦超过该阀值,则输出警告日志,通过选项-XX:LongGCLogThreshold指定。
 870                        runtime_options.Exists(Opt::IgnoreMaxFootprint),
     //不对堆的大小进行限制标志,通过选项-XX:IgnoreMaxFootprint指定。
 871                        runtime_options.GetOrDefault(Opt::UseTLAB),
 872                        xgc_option.verify_pre_gc_heap_,
 873                        xgc_option.verify_pre_sweeping_heap_,
 874                        xgc_option.verify_post_gc_heap_,
 875                        xgc_option.verify_pre_gc_rosalloc_,
 876                        xgc_option.verify_pre_sweeping_rosalloc_,
 877                        xgc_option.verify_post_gc_rosalloc_,
 878                        xgc_option.gcstress_,
 879                        runtime_options.GetOrDefault(Opt::EnableHSpaceCompactForOOM),
 880                        runtime_options.GetOrDefault(Opt::HSpaceCompactForOOMMinIntervalsMs));
     ...
1125 }

根据RuntimeArgumentMap的定义,其中#include “runtime_options.def”,该文件中存了Parse-able keys from the command line。

 59   // Defines a type-safe heterogeneous key->value map.
 60   // Use the VariantMap interface to look up or to store a RuntimeArgumentMapKey,Value pair.
 61   //
 62   // Example:
 63   //    auto map = RuntimeArgumentMap();
 64   //    map.Set(RuntimeArgumentMap::HeapTargetUtilization, 5.0);
 65   //    double *target_utilization = map.Get(RuntimeArgumentMap);
 66   //
 67   struct RuntimeArgumentMap : VariantMap<RuntimeArgumentMap, RuntimeArgumentMapKey> {
 68     // This 'using' line is necessary to inherit the variadic constructor.
 69     using VariantMap<RuntimeArgumentMap, RuntimeArgumentMapKey>::VariantMap;
 70 
 71     // Make the next many usages of Key slightly shorter to type.
 72     template <typename TValue>
 73     using Key = RuntimeArgumentMapKey<TValue>;
 74 
 75     // List of key declarations, shorthand for 'static const Key<T> Name'
 76 #define RUNTIME_OPTIONS_KEY(Type, Name, ...) static const Key<Type> Name;
 77 #include "runtime_options.def"
 78   };

其中的XGcOption的定义为:

//~/android-6.0.1_r62/art/cmdline/cmdline_types.h
461 struct XGcOption { 
462   // These defaults are used when the command line arguments for -Xgc:
463   // are either omitted completely or partially.
464   gc::CollectorType collector_type_ =  kUseReadBarrier ?
465                                            // If RB is enabled (currently a build-time decision),
466                                            // use CC as the default GC.
467                                            gc::kCollectorTypeCC :
468                                            gc::kCollectorTypeDefault;
469   bool verify_pre_gc_heap_ = false;
470   bool verify_pre_sweeping_heap_ = kIsDebugBuild;
471   bool verify_post_gc_heap_ = false;
472   bool verify_pre_gc_rosalloc_ = kIsDebugBuild;
473   bool verify_pre_sweeping_rosalloc_ = false;
474   bool verify_post_gc_rosalloc_ = false;
475   bool gcstress_ = false;
476 }; 

以下为Android4.4中剩余无法对应的部分:
Runtime类的成员函数Init首先是调用ParsedOptions类的静态成员函数Create解析ART运行时的启动选项,并且保存在变量options指向的一个ParsedOptions对象的各个成员变量中,与堆相关的各个选项的含义如下所示:
5. options->heap_target_utilization_: 堆的目标利用率,通过选项-XX:HeapTargetUtilization指定。
8. options->is_concurrent_gc_enabled_: 是否支持并行GC,通过选项-Xgc指定。

接下来我们就继续分析Heap类的构造函数,以便可以了解堆的创建过程,如下所示:

 105 static constexpr bool kGCALotMode = false;
 106 // GC alot mode uses a small allocation stack to stress test a lot of GC.
 107 static constexpr size_t kGcAlotAllocationStackSize = 4 * KB /
    ...
 118 Heap::Heap(size_t initial_size, size_t growth_limit, size_t min_free, size_t max_free,
 119            double target_utilization, double foreground_heap_growth_multiplier,
 120            size_t capacity, size_t non_moving_space_capacity, const std::string& image_file_name,
 121            const InstructionSet image_instruction_set, CollectorType foreground_collector_type,
 122            CollectorType background_collector_type,
 123            space::LargeObjectSpaceType large_object_space_type, size_t large_object_threshold,
 124            size_t parallel_gc_threads, size_t conc_gc_threads, bool low_memory_mode,
 125            size_t long_pause_log_threshold, size_t long_gc_log_threshold,
 126            bool ignore_max_footprint, bool use_tlab,
 127            bool verify_pre_gc_heap, bool verify_pre_sweeping_heap, bool verify_post_gc_heap,
 128            bool verify_pre_gc_rosalloc, bool verify_pre_sweeping_rosalloc,
 129            bool verify_post_gc_rosalloc, bool gc_stress_mode,
 130            bool use_homogeneous_space_compaction_for_oom,
 131            uint64_t min_interval_homogeneous_space_compaction_by_oom)
 132     : non_moving_space_(nullptr),
 133       rosalloc_space_(nullptr),
 134       dlmalloc_space_(nullptr),
 135       main_space_(nullptr),
 136       collector_type_(kCollectorTypeNone),
    ...
 141       parallel_gc_threads_(parallel_gc_threads),
 142       conc_gc_threads_(conc_gc_threads),
 143       low_memory_mode_(low_memory_mode),
 144       long_pause_log_threshold_(long_pause_log_threshold),
 145       long_gc_log_threshold_(long_gc_log_threshold),
 146       ignore_max_footprint_(ignore_max_footprint),
    ...
 153       capacity_(capacity),
 154       growth_limit_(growth_limit),
 155       max_allowed_footprint_(initial_size),
    ...
 176       /* For GC a lot mode, we limit the allocations stacks to be kGcAlotInterval allocations. This
 177        * causes a lot of GC since we do a GC for alloc whenever the stack is full. When heap
 178        * verification is enabled, we limit the size of allocation stacks to speed up their
 179        * searching.
 180        */
 181       max_allocation_stack_size_(kGCALotMode ? kGcAlotAllocationStackSize
 182           : (kVerifyObjectSupport > kVerifyObjectModeFast) ? kVerifyObjectAllocationStackSize :
 183           kDefaultAllocationStackSize),
 184       current_allocator_(kAllocatorTypeDlMalloc),
 185       current_non_moving_allocator_(kAllocatorTypeNonMoving),
 186       bump_pointer_space_(nullptr),
 187       temp_space_(nullptr),
 188       region_space_(nullptr),
 189       min_free_(min_free),
 190       max_free_(max_free),
 191       target_utilization_(target_utilization),
    ...
 {
 219   if (VLOG_IS_ON(heap) || VLOG_IS_ON(startup)) {
 220     LOG(INFO) << "Heap() entering";
 221   }
    ...
 234   live_bitmap_.reset(new accounting::HeapBitmap(this));
 235   mark_bitmap_.reset(new accounting::HeapBitmap(this));

 236   // Requested begin for the alloc space, to follow the mapped image and oat files
 237   uint8_t* requested_alloc_space_begin = nullptr;
 238   if (foreground_collector_type_ == kCollectorTypeCC) {
 239     // Need to use a low address so that we can allocate a contiguous
 240     // 2 * Xmx space when there's no image (dex2oat for target).
 241     CHECK_GE(300 * MB, non_moving_space_capacity);
 242     requested_alloc_space_begin = reinterpret_cast<uint8_t*>(300 * MB) - non_moving_space_capacity;
 243   }
 244   if (!image_file_name.empty()) {
 245     ATRACE_BEGIN("ImageSpace::Create");
 246     std::string error_msg;
 247     auto* image_space = space::ImageSpace::Create(image_file_name.c_str(), image_instruction_set,
 248                                                   &error_msg);
 249     ATRACE_END();
 250     if (image_space != nullptr) {
 251       AddSpace(image_space);
 252       // Oat files referenced by image files immediately follow them in memory, ensure alloc space
 253       // isn't going to get in the middle
 254       uint8_t* oat_file_end_addr = image_space->GetImageHeader().GetOatFileEnd();
 255       CHECK_GT(oat_file_end_addr, image_space->End());
 256       requested_alloc_space_begin = AlignUp(oat_file_end_addr, kPageSize);
 257     } else {
 258       LOG(ERROR) << "Could not create image space with image file '" << image_file_name << "'. "
 259                    << "Attempting to fall back to imageless running. Error was: " << error_msg;
 260     }
 261   }
 262   /*
 263   requested_alloc_space_begin ->     +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
 264                                      +-  nonmoving space (non_moving_space_capacity)+-
 265                                      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
 266                                      +-????????????????????????????????????????????+-
 267                                      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
 268                                      +-main alloc space / bump space 1 (capacity_) +-
 269                                      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
 270                                      +-????????????????????????????????????????????+-
 271                                      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
 272                                      +-main alloc space2 / bump space 2 (capacity_)+-
 273                                      +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
 274   */
    ...
 301   ATRACE_BEGIN("Create heap maps");
 302   if (separate_non_moving_space) {
 303     // If we are the zygote, the non moving space becomes the zygote space when we run
 304     // PreZygoteFork the first time. In this case, call the map "zygote space" since we can't
 305     // rename the mem map later.
 306     const char* space_name = is_zygote ? kZygoteSpaceName: kNonMovingSpaceName;
 307     // Reserve the non moving mem map before the other two since it needs to be at a specific
 308     // address.
 309     non_moving_space_mem_map.reset(
 310         MemMap::MapAnonymous(space_name, requested_alloc_space_begin,
 311                              non_moving_space_capacity, PROT_READ | PROT_WRITE, true, false,
 312                              &error_str));
 313     CHECK(non_moving_space_mem_map != nullptr) << error_str;
 314     // Try to reserve virtual memory at a lower address if we have a separate non moving space.
 315     request_begin = reinterpret_cast<uint8_t*>(300 * MB);
 316   }
    ...
 340   // Create the non moving space first so that bitmaps don't take up the address range.
 341   if (separate_non_moving_space) {
 342     // Non moving space is always dlmalloc since we currently don't have support for multiple
 343     // active rosalloc spaces.
 344     const size_t size = non_moving_space_mem_map->Size();
 345     non_moving_space_ = space::DlMallocSpace::CreateFromMemMap(
 346         non_moving_space_mem_map.release(), "zygote / non moving space", kDefaultStartingSize,
 347         initial_size, size, size, false);
 348     non_moving_space_->SetFootprintLimit(non_moving_space_->Capacity());
 349     CHECK(non_moving_space_ != nullptr) << "Failed creating non moving space "
 350         << requested_alloc_space_begin;
 351     AddSpace(non_moving_space_);
 352   }
    ...
 348     non_moving_space_->SetFootprintLimit(non_moving_space_->Capacity());
    ...
 351     AddSpace(non_moving_space_);
     ...
 418   // Compute heap capacity. Continuous spaces are sorted in order of Begin().
 419   CHECK(!continuous_spaces_.empty());
 420   // Relies on the spaces being sorted.
 421   uint8_t* heap_begin = continuous_spaces_.front()->Begin();
 422   uint8_t* heap_end = continuous_spaces_.back()->Limit();
 423   size_t heap_capacity = heap_end - heap_begin;
    ...
 430   // Allocate the card table.
 431   ATRACE_BEGIN("Create card table");
 432   card_table_.reset(accounting::CardTable::Create(heap_begin, heap_capacity));
 433   CHECK(card_table_.get() != nullptr) << "Failed to create card table";
 434   ATRACE_END();
     ...
 454   num_bytes_allocated_.StoreRelaxed(0);
 455   mark_stack_.reset(accounting::ObjectStack::Create("mark stack", kDefaultMarkStackSize,
 456                                                     kDefaultMarkStackSize));
 457   const size_t alloc_stack_capacity = max_allocation_stack_size_ + kAllocationStackReserveSize;
 458   allocation_stack_.reset(accounting::ObjectStack::Create(
 459       "allocation stack", max_allocation_stack_size_, alloc_stack_capacity));
 460   live_stack_.reset(accounting::ObjectStack::Create(
 461       "live stack", max_allocation_stack_size_, alloc_stack_capacity));
     ...
 470   if (ignore_max_footprint_) {
 471     SetIdealFootprint(std::numeric_limits<size_t>::max());
 472     concurrent_start_bytes_ = std::numeric_limits<size_t>::max();
 473   }
    ...
 475   // Create our garbage collectors.
 476   for (size_t i = 0; i < 2; ++i) {
 477     const bool concurrent = i != 0;
 478     if ((MayUseCollector(kCollectorTypeCMS) && concurrent) ||
 479         (MayUseCollector(kCollectorTypeMS) && !concurrent)) {
 480       garbage_collectors_.push_back(new collector::MarkSweep(this, concurrent));
 481       garbage_collectors_.push_back(new collector::PartialMarkSweep(this, concurrent));
 482       garbage_collectors_.push_back(new collector::StickyMarkSweep(this, concurrent));
 483     }
 484   }

这个函数定义在文件art/runtime/gc/heap.cc中。
Heap类的构造函数就负责创建上面图1所示的各种数据结构,创建过程如下所示:
1. 创建Live Bitmap和Mark Bitmap,它们都是使用一个ContinuousSpaceBitmap对象来描述,并且分别保存在成员变量live_bitmap_和mark_bitmap_中。
2. 如果指定了image文件,即参数original_image_file_name的值不等于空,则调用ImageSpace类的静态成员函数Create创建一个Image Space,并且调用Heap类的成员函数AddSpace将该Image Space添加到一个在地址空间上连续的Space列表中,即Image Space属于地址空间连续的Space。在Image文件的头部,指定了与Image文件关联的boot.art@classes.oat文件加载到内存的结束位置,我们需要将这个位置取出来,并且将它对齐到页面大小,保存变量requested_alloc_space_begin中,作为一会要创建的Zygote Space的开始地址。这样就可以使得Image Space和Zygote Space的布局与图1所示保持一致。
3. 调用DlMallocSpaced的CreateFromMemMap函数创建一个Zygote Space(如果is_ zygote为假,则名为NonMovingSpace),注意第二个参数requested_alloc_space_begin,指定了Zygote Space的起始地址,它刚刚好是紧跟在boot.art@classes.oat文件的后面。这时候代码是运行在Zygote进程中,而Zygote进程中的ART运行时刚开始的时候是没有Zygote Space和Allocation Space之分的。等到Zygote进程fork第一个子进程的时候,才会将这里创建的Zygote Space一分为二,得到一个Zygote Space和一个Allocation Space。这一点与前面Dalvik虚拟机Java堆创建过程分析一文分析Dalvik虚拟机堆的管理是一样的。由于这里创建的Zygote Space也是一个地址空间连续的Space,因此它也会被Heap类的成员函数AddSpace添加一个在地址空间上连续的Space列表中。
4. 接下来是创建Large Object Space。正如前面ART运行时垃圾收集机制简要介绍和学习计划一文所述,ART运行时提供了两种Large Object Space,其中一种是Free List实现FreeListSpace,另外一种是由一组相互独立的内存块组成的LargeObjectMapSpace。这里由于kUseFreeListSpaceForLOS的值设置为false,因此Large Object Space使用的是后一种实现,通过LargeObjectMapSpace类的静态成员函数Create来创建。注意,这里创建的Large Object Space属于地址空间不连续的Space,因此需要调用Heap类的另外一个成员函数AddDiscontinuousSpace将它添加到内部一个在地址空间上不连续的Space列表中。
5. 接下来是计算所有在地址空间上连续的Space占用的内存的大小。此时,地址空间上连续的Space有两个,分别是Image Space和Zygote Space,它们按照地址从小到大的顺序保存在Heap类的成员变量continuous_spaces_描述的一个向量中。由于Image Space的地址小于Zygote Space的地址,因此,保存在Heap类的成员变量continuous_spaces_描述的向量的第一个元素是Image Space,第二个元素是Zygote Space。注意变量heap_capacity的计算,它使用Zygote Space的结束地址减去Image Space的起始地址,得到的大小实际上是包含了图1所示的boot.art@classes.oat文件映射到内存的大小。此外,变量heap_ capacity只是包含了Zygote Space的初始大小,即通过continuous_spaces_.back()->End()得到的大小并没有真实地反映Zygote Space的真实大小,因此这时候需要获得Zygote Space的真实大小,并且增加到变量heap_capacity去。首先,continuous_spaces_ .back()返回的是一个ContinuousSpace指针,但是它实际上指向的是一个子类DlMallocSpace对象。其次,DlMallocSpace提供了函数NonGrowthLimitCapacity用来获得真实大小。因此,将continuous_spaces_.back()返回的是一个ContinuousSpace指针转换为一个DlMallocSpace指针,就可以调用其成员函数NonGrowthLimitCapacity来获得Zygote Space的真实大小,并且添加到变量heap_capacity中去。从这里我们也可以看到,变量heap_capacity描述的是并不是准确的Image Space和Zygote Space的大小之和,而是一个比它们的和要大的一个值。但是变量heap_capacity是用来创建Card Table的,因此它的值比真实的Space的大小大一些不会影响程序的逻辑正确性。
6. 有了所有在地址空间上连续的Space的大小之和heap_capacity,以及地址最小的Space的起始地址heap_begin之后,就可以调用CardTable类的静态成员函数Create来创建一个Card Table了。这里的Card Table的创建过程与前面Dalvik虚拟机Java堆创建过程分析一文分析的Dalvik虚拟机内部使用的Card Table的创建过程是一样的。从这里我们也可以看出,只有地址空间连续的Space才具有Card Table。
7. 接下来是创建用来记录在并行GC阶段,在Image Space上分配的对象对在Zygote Space和Allocation Space上分配的对象的引用的Mod Union Table,以及在Zygote Space上分配的对象对在Allocation Space上分配的对象的引用的Mod Union Table。前一个Mod Union Table使用ModUnionTableToZygoteAllocspace类来描述,后一个Mod Union Table使用ModUnionTableCardCache类来描述。关于ModUnionTableToZygoteAllocspace和ModUnionTableCardCache的关系和用途可以参考前面ART运行时垃圾收集机制简要介绍和学习计划一文。
8. 接下来是创建Mark Stack、Allocation Stack和Live Stack,分别保存在成员变量mark_stack_、allocation_stack_和live_stack_中,它们均是使用一个ObjectStack对象来描述。Mark Stack的初始大小设置为default_ mark_ stack_ size,即64KB。Allocation Stack和Live Stack的初始大小设置为max_ allocation_stack_size_。其值与以下语句有关。kGcAlotAllocationStackSize为4KB,kVerifyObjectAllocationStackSize为16KB,kDefaultAllocationStackSize为8MB。

 181       max_allocation_stack_size_(kGCALotMode ? kGcAlotAllocationStackSize
 182           : (kVerifyObjectSupport > kVerifyObjectModeFast) ? kVerifyObjectAllocationStackSize :
 183           kDefaultAllocationStackSize)
   9. 如果ART运行时启动时指定了-XX:IgnoreMaxFootprint选项,即Heap类的成员变量ignore_max_footprint_的值等于true,那么就需要调用Heap类的成员函数SetIdealFootprint将Heap类的成员变量max_allowed_footprint_的值设置为size_t类型的最大值,即不对堆的大小进行限制。同时也会将Heap类的成员变量concurrent_start_bytes_设置为成员变量max_allowed_footprint_的值,这意味着不会触发并行GC。
   10. 最后创建垃圾收集器,保存在Heap类的成员变量garbage_collectors_描述的一个向量中。这些垃圾收集器一共有两组,其中一组用来执行并行GC,另外一组用来执行非并行GC。每一组都包含三个垃圾收集器,它们分别是MarkSweep、PartialMarkSweep和StickyMarkSweep。关于这三种垃圾收集器的关系和作用,可以参考前面ART运行时垃圾收集机制简要介绍和学习计划一文。

imageheader的内容:

 55 // header of image files written by ImageWriter, read and validated by Space.
 56 class PACKED(4) ImageHeader {
 57  public:
    ...
125   enum ImageMethod {
126     kResolutionMethod,//用来描述一个还未进行解析和链接的ART方法。0
127     kImtConflictMethod,//1  -imt(interface method table)
128     kImtUnimplementedMethod,//2
129     kCalleeSaveMethod,//用来描述一个由被调用者保存非参数使用的通用寄存器以及所有的浮点数寄存器。3
130     kRefsOnlySaveMethod,//用来描述一个由被调用者保存非参数使用的通用寄存器。4
131     kRefsAndArgsSaveMethod,//用来描述一个由被调用者保存参数和非参数使用的通用寄存器。5
132     kImageMethodsCount,  // Number of elements in enum.
133   };
//上面几个特殊的ArtMethod对象从Image Space取出来之后,会通过调用Runtime类的成员函数SetResolutionMethod和SetCalleeSaveMethod保存在用来描述ART运行时的一个Runtime对象的内部,其中,第3/4/5个ArtMethod对象在ART运行时内部对应的类型分别为Runtime::kSaveAll、Runtime::kRefsOnly和Runtime::kRefsAndArgs。
134 
135   enum ImageRoot {
136     kDexCaches,
137     kClassRoots,
138     kImageRootsMax,
139   };
140 
141   enum ImageSections {
142     kSectionObjects,
143     kSectionArtFields,
144     kSectionArtMethods,
145     kSectionInternedStrings,
146     kSectionImageBitmap,
147     kSectionCount,  // Number of elements in enum.
148   };
    ...
169  private:
170   static const uint8_t kImageMagic[4];
171   static const uint8_t kImageVersion[4];
172 
173   uint8_t magic_[4];//image文件魔数,固定为"art\n"
174   uint8_t version_[4];//版本号,固定为"017\0"
175 
176   // Required base address for mapping the image.
177   uint32_t image_begin_;//指定Image Space映射到内存的起始地址。
178 
179   // Image size, not page aligned.
180   uint32_t image_size_;//image Space大小
181 
182   // Checksum of the oat file we link to for load time sanity check.
183   uint32_t oat_checksum_;//与Image文件关联的boot.art@classes.oat文件的检验值。
184 
185   // Start address for oat file. Will be before oat_data_begin_ for .so files.
186   uint32_t oat_file_begin_;//与Image文件关联的boot.art@classes.oat文件映射到内存的起始位置。
187 
188   // Required oat address expected by image Method::GetCode() pointers.
189   uint32_t oat_data_begin_;//
190 
191   // End of oat data address range for this image file.
192   uint32_t oat_data_end_;
193 
194   // End of oat file address range. will be after oat_data_end_ for
195   // .so files. Used for positioning a following alloc spaces.
196   uint32_t oat_file_end_;//与Image文件关联的boot.art@classes.oat文件映射到内存的结束位置。
197 
198   // The total delta that this image has been patched.
199   int32_t patch_delta_;
200 
201   // Absolute address of an Object[] of objects needed to reinitialize from an image.
202   uint32_t image_roots_;
203 
204   // Pointer size, this affects the size of the ArtMethods.
205   uint32_t pointer_size_;
206 
207   // Boolean (0 or 1) to denote if the image was compiled with --compile-pic option
208   const uint32_t compile_pic_;
209 
210   // Image sections
211   ImageSection sections_[kSectionCount];
212 
213   // Image methods.
214   uint64_t image_methods_[kImageMethodsCount];
215 
216   friend class ImageWriter;
217 };

关于Image Space:
1. Image Space的回收策略为kGcRetentionPolicyNeverCollect,即永远不会进行垃圾回收。
2. Image Space是一个在地址空间上连续的Space,因为它是通过父类MemMapSpace来管理Space的。
3. Image Space的对象的存活是通过Space Bitmap来标记的。注意,Image Space不像其它Space一样,有Live和Mark两个Bitmap。它们而是共用一个Bitmap,这是由于Image Space永远不会进行垃圾回收。
上面在创建imageSpace时用到了ImageSpace::Create,而该函数中用到了space = ImageSpace::Init(cache_filename.c_str(), image_location, true, error_msg);
而init函数中用到了 space->oat_file_.reset(space->OpenOatFile(image_filename, error_msg)); 打开oatfile时用到了OatFile类的方法Open,将与前面创建的Image Space关联的OAT文件也加载到内存来。可参见前面的文章。

792   OatFile* oat_file = OatFile::Open(oat_filename, oat_filename, image_header.GetOatDataBegin(),
793                                     image_header.GetOatFileBegin(),
794                                     !Runtime::Current()->IsAotCompiler(),
795                                     nullptr, error_msg);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值