通过前面的博客我们知道在art 创建的时候,会创建出heap实例,也就是管理art 的堆的对象。
art/runtime/runtime.cc
932 bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
...
1015 heap_ = new gc::Heap(runtime_options.GetOrDefault(Opt::MemoryInitialSize),
1016 runtime_options.GetOrDefault(Opt::HeapGrowthLimit),
1017 runtime_options.GetOrDefault(Opt::HeapMinFree),
1018 runtime_options.GetOrDefault(Opt::HeapMaxFree),
1019 runtime_options.GetOrDefault(Opt::HeapTargetUtilization),
1020 runtime_options.GetOrDefault(Opt::ForegroundHeapGrowthMultiplier),
1021 runtime_options.GetOrDefault(Opt::MemoryMaximumSize),
1022 runtime_options.GetOrDefault(Opt::NonMovingSpaceCapacity),
1023 runtime_options.GetOrDefault(Opt::Image),
1024 runtime_options.GetOrDefault(Opt::ImageInstructionSet),
1025 xgc_option.collector_type_,
1026 runtime_options.GetOrDefault(Opt::BackgroundGc),
1027 runtime_options.GetOrDefault(Opt::LargeObjectSpace),
1028 runtime_options.GetOrDefault(Opt::LargeObjectThreshold),
1029 runtime_options.GetOrDefault(Opt::ParallelGCThreads),
1030 runtime_options.GetOrDefault(Opt::ConcGCThreads),
1031 runtime_options.Exists(Opt::LowMemoryMode),
1032 runtime_options.GetOrDefault(Opt::LongPauseLogThreshold),
1033 runtime_options.GetOrDefault(Opt::LongGCLogThreshold),
1034 runtime_options.Exists(Opt::IgnoreMaxFootprint),
1035 runtime_options.GetOrDefault(Opt::UseTLAB),
1036 xgc_option.verify_pre_gc_heap_,
1037 xgc_option.verify_pre_sweeping_heap_,
1038 xgc_option.verify_post_gc_heap_,
1039 xgc_option.verify_pre_gc_rosalloc_,
1040 xgc_option.verify_pre_sweeping_rosalloc_,
1041 xgc_option.verify_post_gc_rosalloc_,
1042 xgc_option.gcstress_,
1043 runtime_options.GetOrDefault(Opt::EnableHSpaceCompactForOOM),
1044 runtime_options.GetOrDefault(Opt::HSpaceCompactForOOMMinIntervalsMs));
1045
1046 if (!heap_->HasBootImageSpace() && !allow_dex_file_fallback_) {
1047 LOG(ERROR) << "Dex file fallback disabled, cannot continue without image.";
1048 return false;
1049 }
...
1310 return true;
1311 }
接下里我们分析一下heap 创建过程中做了什么,主要是把创建不同space 的代码列出来。
art/runtime/gc/heap.cc
128 Heap::Heap(size_t initial_size,
...
157 uint64_t min_interval_homogeneous_space_compaction_by_oom)
158 : non_moving_space_(nullptr),
...
250 gc_disabled_for_shutdown_(false) {
...
267 live_bitmap_.reset(new accounting::HeapBitmap(this)); //记录上一次gc后还存活的对象
268 mark_bitmap_.reset(new accounting::HeapBitmap(this)); //记录当前gc后还存活的对象
...
278 // Load image space(s).
279 if (!image_file_name.empty()) { //image_file_name 这个参数是 /system/framework/arm64/boot.art
280 // For code reuse, handle this like a work queue.
281 std::vector<std::string> image_file_names;
282 image_file_names.push_back(image_file_name); //将image_file_name 放到集合中,这时只有一个元素
...
287 for (size_t index = 0; index < image_file_names.size(); ++index) { //开始只有一个元素,但是往下运行的时候又添加了几个
288 std::string& image_name = image_file_names[index];
289 std::string error_msg;
290 space::ImageSpace* boot_image_space = space::ImageSpace::CreateBootImage( //打开art文件,映射到内存,同时加载对应的oat文件
291 image_name.c_str(),
292 image_instruction_set,
293 index > 0,
294 &error_msg);
295 if (boot_image_space != nullptr) {
296 AddSpace(boot_image_space); //加到space里面
...
305 if (index == 0) { //是第一个元素的时候,判断是否还有要加载的art文件
306 // If this was the first space, check whether there are more images to load.
307 const OatFile* boot_oat_file = boot_image_space->GetOatFile();
308 if (boot_oat_file == nullptr) {
309 continue;
310 }
311
312 const OatHeader& boot_oat_header = boot_oat_file->GetOatHeader();
313 const char* boot_classpath =
314 boot_oat_header.GetStoreValueByKey(OatHeader::kBootClassPathKey);
315 if (boot_classpath == nullptr) {
316 continue;
317 }
318 //将其他要加载的art文件放到image_file_names 集合中,所以这个集合的长度不是1了
319 space::ImageSpace::ExtractMultiImageLocations(image_file_name,
320 boot_classpath,
321 &image_file_names);
322 }
323 } else {
...
336 }
337 }
...
369 std::unique_ptr<MemMap> main_mem_map_1;
370 std::unique_ptr<MemMap> main_mem_map_2;
...
385 std::unique_ptr<MemMap> non_moving_space_mem_map;
... //static const char* kZygoteSpaceName = "zygote space";
391 const char* space_name = is_zygote ? kZygoteSpaceName: kNonMovingSpaceName;
394 non_moving_space_mem_map.reset( //映射的是zygote space
395 MemMap::MapAnonymous(space_name, requested_alloc_space_begin,
396 non_moving_space_capacity, PROT_READ | PROT_WRITE, true, false,
397 &error_str));
...
// static const char* kMemMapSpaceName[2] = {"main space", "ma