ART runtime的java堆

参考http://blog.csdn.net/luoshengyang/article/details/42379729 罗升阳老师的 ART运行时Java堆创建过程分析 一文:

Init函数定义在~/android-6.0.1_r62/art/runtime/runtime.cc中:

 782 bool Runtime::Init(const RuntimeOptions& raw_options, bool ignore_unrecognized) {
...
 788   using Opt = RuntimeArgumentMap;//此处using的用法等同于typedef
 789   RuntimeArgumentMap runtime_options;
 790   std::unique_ptr<ParsedOptions> parsed_options(
 791       ParsedOptions::Create(raw_options, ignore_unrecognized, &runtime_options));
 ...
  849   XGcOption xgc_option = runtime_options.GetOrDefault(Opt::GcOption);
  850   ATRACE_BEGIN("CreateHeap");
  // 以下的这些都可以在 std::unique_ptr<RuntimeParser> ParsedOptions::MakeParser(bool ignore_unrecognized)中找到
851   heap_ = new gc::Heap(runtime_options.GetOrDefault(Opt::MemoryInitialSize),//由-Xms_指定,内存初始化大小
 852                        runtime_options.GetOrDefault(Opt::HeapGrowthLimit),//由-XX:HeapGrowthLimit=_指定,堆允许增长的上限值,这是堆的一个软上限值。
 853                        runtime_options.GetOrDefault(Opt::HeapMinFree),//堆的最小空闲值,通过-XX:HeapMinFree=_指定
 854                        runtime_options.GetOrDefault(Opt::HeapMaxFree),//堆的最大空闲值,通过-XX:HeapMaxFree=_指定
 855                        runtime_options.GetOrDefault(Opt::HeapTargetUtilization),
 856                        runtime_options.GetOrDefault(Opt::ForegroundHeapGrowthMultiplier),
 857                        runtime_options.GetOrDefault(Opt::MemoryMaximumSize),
 858                        runtime_options.GetOrDefault(Opt::NonMovingSpaceCapacity),
 859                        runtime_options.GetOrDefault(Opt::Image),//用来创建Image Space的Image文件,通过选项-Ximage指定。
 860                        runtime_options.GetOrDefault(Opt::ImageInstructionSet),
 861                        xgc_option.collector_type_,
 862                        runtime_options.GetOrDefault(Opt::BackgroundGc),
 863                        runtime_options.GetOrDefault(Opt::LargeObjectSpace),
 864                        runtime_options.GetOrDefault(Opt::LargeObjectThreshold),
 865                        runtime_options.GetOrDefault(Opt::ParallelGCThreads),
 866                        runtime_options.GetOrDefault(Opt::ConcGCThreads),
 867                        runtime_options.Exists(Opt::LowMemoryMode),
 868                        runtime_options.GetOrDefault(Opt::LongPauseLogThreshold),
 869                        runtime_options.GetOrDefault(Opt::LongGCLogThreshold),
 870                        runtime_options.Exists(Opt::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));
 ...
 }

首先Init调用ParsedOptions::Create来解析ART运行时的启动选项,并且保存在变量runtime_options指向的一个ParsedOption对象的各个成员变量中。
接下来继续分析Heap类的构造函数,以便可以了解堆的创建过程:

 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),
 137       foreground_collector_type_(foreground_collector_type),
 138       background_collector_type_(background_collector_type),
 139       desired_collector_type_(foreground_collector_type_),
 140       pending_task_lock_(nullptr),
 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),
 147       zygote_creation_lock_("zygote creation lock", kZygoteCreationLock),
 148       zygote_space_(nullptr),
 149       large_object_threshold_(large_object_threshold),
 150       collector_type_running_(kCollectorTypeNone),
 151       last_gc_type_(collector::kGcTypeNone),
 152       next_gc_type_(collector::kGcTypePartial),
...
//1. 创建Live Bitmap和Mark Bitmap,它们都是使用一个HeapBitmap对象来描述,并且分别保存在成员变量live_bitmap_和mark_bitmap_中。
 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;
    //如果参数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所示保持一致。
 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   }

...
}

ImageSpace::Create调用ImageSpace::Init来构建堆,Init中又有ImageHeader类的实例 ImageHeader image_header;
来看header中的私有变量:

 56 class PACKED(4) ImageHeader {
 /*header of image files written by ImageWriter, read and validated by Space.*/
 ...
169  private:
170   static const uint8_t kImageMagic[4];
171   static const uint8_t kImageVersion[4];
172 
173   uint8_t magic_[4];//文件魔数,固定为'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_;//与Image文件关联的boot.art@classes.oat文件的OATDATA段映射到内存的起始位置。
190 
191   // End of oat data address range for this image file.
192   uint32_t oat_data_end_;//与Image文件关联的boot.art@classes.oat文件的OATDATA段映射到内存的结束位置。
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_;//与Image文件关联的boot.art@classes.oat文件映射到内存的结束位置。
203 
204   // Pointer size, this affects the size of the ArtMethods.
205   uint32_t pointer_size_;//指针大小,这影响ArtMethods的大小,与架构有关。
206 
207   // Boolean (0 or 1) to denote if the image was compiled with --compile-pic option
208   const uint32_t compile_pic_;//0或1,代表是否image由--compile-pic选项编译。
209 
210   // Image sections
211   ImageSection sections_[kSectionCount];
212 
213   // Image methods.
214   uint64_t image_methods_[kImageMethodsCount];
...
}

在Image文件头的成员变量image_roots_描述的对象数组中,有四个特殊的ArtMethod对象,用来描述四种特殊的ART运行时方法。ART运行时方法是一种用来描述其它ART方法的ART方法。它们具有特殊的用途,如下所示:
1. ImageHeader::kResolutionMethod: 用来描述一个还未进行解析和链接的ART方法。
2. ImageHeader::kCalleeSaveMethod: 用来描述一个由被调用者保存的r4-r11、lr和s0-s31寄存器的ART方法,即由被调用者保存非参数使用的通用寄存器以及所有的浮点数寄存器。
3. ImageHeader::kRefsOnlySaveMethod: 用来描述一个由被调用者保存的X19-X29和xLR寄存器的ART方法,即由被调用者保存非参数使用的通用寄存器。
4. ImageHeader::kRefsAndArgsSaveMethod: 用来描述一个由被调用者保存的X0-X7、X19-X29和XLR寄存器的ART方法,即由被调用者保存参数和非参数使用的通用寄存器。
X0用来保存当前调用的ART方法,X1-X7寄存器用来传递前7个参数,其它参数通过栈来传递.栈顶由sp(x31)寄存器指定,(?)寄存器用来保存一个在GC过程中使用到的线程挂起计数器,x8-x15寄存器用来分配给局部变量使用,X18(xSELF)寄存器用来保存当前调用线程对象,Xlr(X30)寄存器用来保存当前ART方法的返回地址,pc寄存器用来保存当前执行的指令地址。
上面四个特殊的ArtMethod对象从Image Space取出来之后,会通过调用Runtime类的成员函数SetResolutionMethod和SetCalleeSaveMethod保存在用来描述ART运行时的一个Runtime对象的内部,其中,第2、3和4个ArtMethod对象在ART运行时内部对应的类型分别为Runtime::kSaveAll、Runtime::kRefsOnly和Runtime::kRefsAndArgs。

371   enum CalleeSaveType {
372     kSaveAll,
373     kRefsOnly,
374     kRefsAndArgs,
375     kLastCalleeSaveType  // Value used for iteration
376   };

接下来看ImageSpace的构造函数:

 46 ImageSpace::ImageSpace(const std::string& image_filename, const char* image_location,
 47                        MemMap* mem_map, accounting::ContinuousSpaceBitmap* live_bitmap,
 48                        uint8_t* end)
 49     : MemMapSpace(image_filename, mem_map, mem_map->Begin(), end, end,
 50                   kGcRetentionPolicyNeverCollect),
 51       image_location_(image_location) {
 52   DCHECK(live_bitmap != nullptr);
 53   live_bitmap_.reset(live_bitmap);
 54 }

从这里就可以看出:

   1. Image Space的回收策略为kGcRetentionPolicyNeverCollect,即永远不会进行垃圾回收。
   2. Image Space是一个在地址空间上连续的Space,因为它是通过父类MemMapSpace来管理Space的。
   3. Image Space的对象的存活是通过ContinuousSpaceBitmap来标记的。注意,Image Space不像其它Space一样,有Live和Mark两个Bitmap。它们而是共用一个Bitmap,这是由于Image Space永远不会进行垃圾回收。

待续

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值