art heap创建流程

来源:互联网 发布:iphone所有软件打不开 编辑:程序博客网 时间:2024/06/05 14:28

通过前面的博客我们知道在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.art280      // 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 space395          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", "main space 1"};406        main_mem_map_1.reset(MapAnonymousPreferredAddress(kMemMapSpaceName[0], // 映射的是main space407                                                          request_begin,408                                                          capacity_,...424      main_mem_map_2.reset(MapAnonymousPreferredAddress(kMemMapSpaceName[1], main_mem_map_1->End(), // 映射的是main space 1425                                                        capacity_, &error_str));...435      non_moving_space_ = space::DlMallocSpace::CreateFromMemMap(  //构建 zygote space436          non_moving_space_mem_map.release(), "zygote / non moving space", kDefaultStartingSize,437          initial_size, size, size, false);441     AddSpace(non_moving_space_);  //添加到 space443   // Create other spaces based on whether or not we have a moving GC.444    if (foreground_collector_type_ == kCollectorTypeCC) { //foreground_collector_type_ 为 kCollectorTypeSS...447    } else if (IsMovingGc(foreground_collector_type_) &&448        foreground_collector_type_ != kCollectorTypeGSS) {449      // Create bump pointer spaces.450      // We only to create the bump pointer if the foreground collector is a compacting GC.451      // TODO: Place bump-pointer spaces somewhere to minimize size of card table.452      bump_pointer_space_ = space::BumpPointerSpace::CreateFromMemMap("Bump pointer space 1",  //构建main space453                                                                      main_mem_map_1.release());454      CHECK(bump_pointer_space_ != nullptr) << "Failed to create bump pointer space";455      AddSpace(bump_pointer_space_);  //添加到 space456      temp_space_ = space::BumpPointerSpace::CreateFromMemMap("Bump pointer space 2",   //构建main space 1457                                                              main_mem_map_2.release());458      CHECK(temp_space_ != nullptr) << "Failed to create bump pointer space";459      AddSpace(temp_space_);  //添加到 space460      CHECK(separate_non_moving_space);461    } else { ...489    }...492    // Allocate the large object space.493    if (large_object_space_type == space::LargeObjectSpaceType::kFreeList) {494     large_object_space_ = space::FreeListSpace::Create("free list large object space", nullptr, //构建large object space495                                                        capacity_);496     CHECK(large_object_space_ != nullptr) << "Failed to create large object space";497   } else if (large_object_space_type == space::LargeObjectSpaceType::kMap) {...500    } else {...504    }505    if (large_object_space_ != nullptr) {506      AddSpace(large_object_space_);   //添加到 space507    }...526    static constexpr size_t kMinHeapAddress = 4 * KB;527    card_table_.reset(accounting::CardTable::Create(reinterpret_cast<uint8_t*>(kMinHeapAddress), //构建 card table528                                                    4 * GB - kMinHeapAddress));...       //创建用来记录ImageSpace对ZygoteSpace引用情况的ModUnionTable534    if (HasBootImageSpace()) {537      for (space::ImageSpace* image_space : GetBootImageSpaces()) {538        accounting::ModUnionTable* mod_union_table = new accounting::ModUnionTableToZygoteAllocspace(541        AddModUnionTable(mod_union_table);542      }543    }       //创建用来记录Non-moving Space对其他Space引用情况的RememberedSet544    if (collector::SemiSpace::kUseRememberedSet && non_moving_space_ != main_space_) {545      accounting::RememberedSet* non_moving_space_rem_set =546          new accounting::RememberedSet("Non-moving space remembered set", this, non_moving_space_);547      CHECK(non_moving_space_rem_set != nullptr) << "Failed to create non-moving space remembered set";548      AddRememberedSet(non_moving_space_rem_set);549   }550   // TODO: Count objects in the image space here?...     //创键一个Semi-Space Collector586    if (kMovingCollector) {587      if (MayUseCollector(kCollectorTypeSS) || MayUseCollector(kCollectorTypeGSS) ||588          MayUseCollector(kCollectorTypeHomogeneousSpaceCompact) ||589          use_homogeneous_space_compaction_for_oom_) {590        // TODO: Clean this up.591        const bool generational = foreground_collector_type_ == kCollectorTypeGSS;592        semi_space_collector_ = new collector::SemiSpace(this, generational,593                                                         generational ? "generational" : "");594        garbage_collectors_.push_back(semi_space_collector_);595      }...604    }...631    if (VLOG_IS_ON(heap) || VLOG_IS_ON(startup)) {632      LOG(INFO) << "Heap() exiting";633    }634  }

上面只是把heap创建过程的关键代码贴了出来,为了直观地看出heap创建后的内存分布,我们把zygote进程空间信息抓出来。

这里以zygote64进程为例

12c00000-12e08000 rw-p 00000000 00:04 2257                               /dev/ashmem/dalvik-main space (deleted)  //main space  2080k12e08000-2ac00000 ---p 00208000 00:04 2257                               /dev/ashmem/dalvik-main space (deleted)   //main space 391136k2ac00000-2ac01000 rw-p 00000000 00:04 2258                               /dev/ashmem/dalvik-main space 1 (deleted) //main space 12ac01000-42c00000 ---p 00001000 00:04 2258                               /dev/ashmem/dalvik-main space 1 (deleted)42c00000-5ac00000 rw-p 00000000 00:04 2267                               /dev/ashmem/dalvik-free list large object space (deleted) // arge object space6f525000-6f7c5000 rw-p 00000000 fe:20 35225                              /data/dalvik-cache/arm64/system@framework@boot.art  //image space6f7c5000-6f941000 rw-p 00000000 fe:20 35226                              /data/dalvik-cache/arm64/system@framework@boot-core-libart.art6f941000-6f976000 rw-p 00000000 fe:20 35227                              /data/dalvik-cache/arm64/system@framework@boot-conscrypt.art6f976000-6f9af000 rw-p 00000000 fe:20 35228                              /data/dalvik-cache/arm64/system@framework@boot-okhttp.art6f9af000-6f9b2000 rw-p 00000000 fe:20 35229                              /data/dalvik-cache/arm64/system@framework@boot-core-junit.art6f9b2000-6f9f8000 rw-p 00000000 fe:20 35230                              /data/dalvik-cache/arm64/system@framework@boot-bouncycastle.art6f9f8000-6fa3a000 rw-p 00000000 fe:20 35231                              /data/dalvik-cache/arm64/system@framework@boot-ext.art6fa3a000-701f6000 rw-p 00000000 fe:20 35232                              /data/dalvik-cache/arm64/system@framework@boot-framework.art701f6000-70286000 rw-p 00000000 fe:20 35233                              /data/dalvik-cache/arm64/system@framework@boot-telephony-common.art70286000-7028e000 rw-p 00000000 fe:20 35234                              /data/dalvik-cache/arm64/system@framework@boot-voip-common.art7028e000-7029a000 rw-p 00000000 fe:20 35235                              /data/dalvik-cache/arm64/system@framework@boot-ims-common.art7029a000-702bd000 rw-p 00000000 fe:20 35236                              /data/dalvik-cache/arm64/system@framework@boot-apache-xml.art702bd000-702e4000 rw-p 00000000 fe:20 35237                              /data/dalvik-cache/arm64/system@framework@boot-org.apache.http.legacy.boot.art702e4000-70831000 r--p 00000000 fe:00 1000                               /system/framework/arm64/boot.oat70831000-70c34000 r-xp 0054d000 fe:00 1000                               /system/framework/arm64/boot.oat70c34000-70c35000 r--p 00950000 fe:00 1000                               /system/framework/arm64/boot.oat70c35000-70c36000 rw-p 00951000 fe:00 1000                               /system/framework/arm64/boot.oat70c36000-710d6000 r--p 00000000 fe:00 984                                /system/framework/arm64/boot-core-libart.oat710d6000-713ee000 r-xp 004a0000 fe:00 984                                /system/framework/arm64/boot-core-libart.oat713ee000-713ef000 r--p 007b8000 fe:00 984                                /system/framework/arm64/boot-core-libart.oat713ef000-713f0000 rw-p 007b9000 fe:00 984                                /system/framework/arm64/boot-core-libart.oat713f0000-71460000 r--p 00000000 fe:00 980                                /system/framework/arm64/boot-conscrypt.oat71460000-714b9000 r-xp 00070000 fe:00 980                                /system/framework/arm64/boot-conscrypt.oat714b9000-714ba000 r--p 000c9000 fe:00 980                                /system/framework/arm64/boot-conscrypt.oat714ba000-714bb000 rw-p 000ca000 fe:00 980                                /system/framework/arm64/boot-conscrypt.oat714bb000-71545000 r--p 00000000 fe:00 992                                /system/framework/arm64/boot-okhttp.oat71545000-715aa000 r-xp 0008a000 fe:00 992                                /system/framework/arm64/boot-okhttp.oat715aa000-715ab000 r--p 000ef000 fe:00 992                                /system/framework/arm64/boot-okhttp.oat715ab000-715ac000 rw-p 000f0000 fe:00 992                                /system/framework/arm64/boot-okhttp.oat715ac000-715b5000 r--p 00000000 fe:00 982                                /system/framework/arm64/boot-core-junit.oat715b5000-715b8000 r-xp 00009000 fe:00 982                                /system/framework/arm64/boot-core-junit.oat715b8000-715b9000 r--p 0000c000 fe:00 982                                /system/framework/arm64/boot-core-junit.oat715b9000-715ba000 rw-p 0000d000 fe:00 982                                /system/framework/arm64/boot-core-junit.oat715ba000-71725000 r--p 00000000 fe:00 978                                /system/framework/arm64/boot-bouncycastle.oat71725000-7176d000 r-xp 0016b000 fe:00 978                                /system/framework/arm64/boot-bouncycastle.oat7176d000-7176e000 r--p 001b3000 fe:00 978                                /system/framework/arm64/boot-bouncycastle.oat7176e000-7176f000 rw-p 001b4000 fe:00 978                                /system/framework/arm64/boot-bouncycastle.oat7176f000-7188c000 r--p 00000000 fe:00 986                                /system/framework/arm64/boot-ext.oat7188c000-718d0000 r-xp 0011d000 fe:00 986                                /system/framework/arm64/boot-ext.oat718d0000-718d1000 r--p 00161000 fe:00 986                                /system/framework/arm64/boot-ext.oat718d1000-718d2000 rw-p 00162000 fe:00 986                                /system/framework/arm64/boot-ext.oat718d2000-72f58000 r--p 00000000 fe:00 988                                /system/framework/arm64/boot-framework.oat72f58000-7400e000 r-xp 01686000 fe:00 988                                /system/framework/arm64/boot-framework.oat7400e000-7400f000 r--p 0273c000 fe:00 988                                /system/framework/arm64/boot-framework.oat7400f000-74010000 rw-p 0273d000 fe:00 988                                /system/framework/arm64/boot-framework.oat74010000-74308000 r--p 00000000 fe:00 996                                /system/framework/arm64/boot-telephony-common.oat74308000-74522000 r-xp 002f8000 fe:00 996                                /system/framework/arm64/boot-telephony-common.oat74522000-74523000 r--p 00512000 fe:00 996                                /system/framework/arm64/boot-telephony-common.oat74523000-74524000 rw-p 00513000 fe:00 996                                /system/framework/arm64/boot-telephony-common.oat74524000-74554000 r--p 00000000 fe:00 998                                /system/framework/arm64/boot-voip-common.oat74554000-74566000 r-xp 00030000 fe:00 998                                /system/framework/arm64/boot-voip-common.oat74566000-74567000 r--p 00042000 fe:00 998                                /system/framework/arm64/boot-voip-common.oat74567000-74568000 rw-p 00043000 fe:00 998                                /system/framework/arm64/boot-voip-common.oat74568000-74595000 r--p 00000000 fe:00 990                                /system/framework/arm64/boot-ims-common.oat74595000-745b3000 r-xp 0002d000 fe:00 990                                /system/framework/arm64/boot-ims-common.oat745b3000-745b4000 r--p 0004b000 fe:00 990                                /system/framework/arm64/boot-ims-common.oat745b4000-745b5000 rw-p 0004c000 fe:00 990                                /system/framework/arm64/boot-ims-common.oat745b5000-74705000 r--p 00000000 fe:00 976                                /system/framework/arm64/boot-apache-xml.oat74705000-7472a000 r-xp 00150000 fe:00 976                                /system/framework/arm64/boot-apache-xml.oat7472a000-7472b000 r--p 00175000 fe:00 976                                /system/framework/arm64/boot-apache-xml.oat7472b000-7472c000 rw-p 00176000 fe:00 976                                /system/framework/arm64/boot-apache-xml.oat7472c000-747da000 r--p 00000000 fe:00 994                                /system/framework/arm64/boot-org.apache.http.legacy.boot.oat747da000-74851000 r-xp 000ae000 fe:00 994                                /system/framework/arm64/boot-org.apache.http.legacy.boot.oat74851000-74852000 r--p 00125000 fe:00 994                                /system/framework/arm64/boot-org.apache.http.legacy.boot.oat74852000-74853000 rw-p 00126000 fe:00 994                                /system/framework/arm64/boot-org.apache.http.legacy.boot.oat74853000-7495b000 rw-p 00000000 00:04 2256                               /dev/ashmem/dalvik-zygote space (deleted)     //zygote space7495b000-7495c000 rw-p 00000000 00:04 3310                               /dev/ashmem/dalvik-non moving space (deleted)7495c000-78354000 ---p 00001000 00:04 3310                               /dev/ashmem/dalvik-non moving space (deleted)78354000-78853000 rw-p 039f9000 00:04 3310                               /dev/ashmem/dalvik-non moving space (deleted)5564760000-5564764000 r-xp 00000000 fe:00 273                            /system/bin/app_process64 //zygote进程的.text段5564764000-5564765000 r--p 00003000 fe:00 273                            /system/bin/app_process64 5564765000-5564766000 rw-p 00004000 fe:00 273                            /system/bin/app_process64 7c30172000-7c30772000 rw-p 00000000 00:04 3309                           /dev/ashmem/dalvik-allocspace main rosalloc space mark-bitmap 3 (deleted)7c30772000-7c30d72000 rw-p 00000000 00:04 3308                           /dev/ashmem/dalvik-allocspace main rosalloc space live-bitmap 3 (deleted)...           //映射到进程中的其他so,文件等                       7c46b02000-7c46bab000 r-xp 00000000 fe:00 397                            /system/bin/linker647c46bab000-7c46bac000 r--p 00000000 00:00 0                              [anon:atexit handlers]7c46bac000-7c46baf000 r--p 000a9000 fe:00 397                            /system/bin/linker647c46baf000-7c46bb0000 rw-p 000ac000 fe:00 397                            /system/bin/linker647c46bb0000-7c46bb3000 rw-p 00000000 00:00 0 7c46bb3000-7c46bb4000 r--p 00000000 00:00 0 7c46bb4000-7c46bb7000 rw-p 00000000 00:00 0 7fdf2eb000-7fdf2eb000 ---p 00000000 00:00 0 7fdf2eb000-7fdfaea000 rw-p 00000000 00:00 0                              [stack]   //进程的栈

main space ,main space 1 和 large object space 占用的空间大小都是384M,这个是根据设置的参数有关,也就是heap size。



zygote space 计算出来是1056K,non moving space 是62M,映射的boot.art,boot.oat和 boot-xx.art,boot-xx.oat 文件所占的空间,我们统一为image space,大小是83M。


上面是zygote64 进程的内存分布,这和zygote进程(32位)可能会有不一样,我们在java代码中创建的object 都是在这块内存中。

290        space::ImageSpace* boot_image_space = space::ImageSpace::CreateBootImage(291            image_name.c_str(),292            image_instruction_set,293            index > 0,294            &error_msg);

art/runtime/gc/space/image_space.cc

371  ImageSpace* ImageSpace::CreateBootImage(const char* image_location,372                                          const InstructionSet image_isa,373                                          bool secondary_image,374                                          std::string* error_msg) {...391    ImageSpace* space;...495        // If we are in /system we can assume the image is good. We can also496        // assume this if we are using a relocated image (i.e. image checksum497        // matches) since this is only different by the offset. We need this to498        // make sure that host tests continue to work.499        // Since we are the boot image, pass null since we load the oat file from the boot image oat500        // file name.501        space = ImageSpace::Init(image_filename->c_str(),502                                 image_location,503                                 !(is_system || relocated_version_used),504                                 /* oat_file */nullptr,505                                 error_msg);507      if (space != nullptr) {...519       return space;520     }...571      // Note that we must not use the file descriptor associated with572      // ScopedFlock::GetFile to Init the image file. We want the file573      // descriptor (and the associated exclusive lock) to be released when574      // we leave Create.575      ScopedFlock image_lock;576      image_lock.Init(cache_filename.c_str(), error_msg);577      space = ImageSpace::Init(cache_filename.c_str(), image_location, true, nullptr, error_msg);578      if (space == nullptr) {579        *error_msg = StringPrintf("Failed to load generated image '%s': %s",580                                  cache_filename.c_str(), error_msg->c_str());581      }582      return space;584  }
这里不详解介绍创建过程中的处理逻辑,各种判断条件就不列出来了,我们只看实现部分的代码就可以了。

1149  ImageSpace* ImageSpace::Init(const char* image_filename,1150                               const char* image_location,1151                               bool validate_oat_file,1152                               const OatFile* oat_file,1153                               std::string* error_msg) {...1160    std::unique_ptr<File> file;1161    {1162      TimingLogger::ScopedTiming timing("OpenImageFile", &logger);1163      file.reset(OS::OpenFileForReading(image_filename));  //打开art文件1168    }1169    ImageHeader temp_image_header;1170    ImageHeader* image_header = &temp_image_header;1171    {1172      TimingLogger::ScopedTiming timing("ReadImageHeader", &logger);1173      bool success = file->ReadFully(image_header, sizeof(*image_header)); //将art文件头部信息读取出来,头部内容就是一个ImageHeader结构体1178    }...1234    // Note: The image header is part of the image due to mmap page alignment required of offset.1235    std::unique_ptr<MemMap> map;1236    std::string temp_error_msg;1237    for (uint8_t* address : addresses) {...1243      if (storage_mode == ImageHeader::kStorageModeUncompressed) {1244        map.reset(MemMap::MapFileAtAddress(address,           //映射到内存中1245                                           image_header->GetImageSize(),1246                                           PROT_READ | PROT_WRITE,1247                                           MAP_PRIVATE,1248                                           file->Fd(),1249                                           0,1250                                           /*low_4gb*/true,1251                                           /*reuse*/false,1252                                           image_filename,1253                                           /*out*/out_error_msg));1254      } else {...1305      }1306    }...1315    std::unique_ptr<MemMap> image_bitmap_map(MemMap::MapFileAtAddress(nullptr, //将art文件中的1316                                                                      bitmap_section.Size(),1317                                                                      PROT_READ, MAP_PRIVATE,1318                                                                      file->Fd(),1319                                                                      image_bitmap_offset,1320                                                                      /*low_4gb*/false,1321                                                                      /*reuse*/false,1322                                                                      image_filename,1323                                                                      error_msg));...1363    // We only want the mirror object, not the ArtFields and ArtMethods.1364    std::unique_ptr<ImageSpace> space(new ImageSpace(image_filename,  //创建space 管理空间1365                                                     image_location,1366                                                     map.release(),1367                                                     bitmap.release(),1368                                                     image_end));1375    if (oat_file == nullptr) {1376      TimingLogger::ScopedTiming timing("OpenOatFile", &logger);1377      space->oat_file_.reset(space->OpenOatFile(image_filename, error_msg)); //打开oat文件1382      space->oat_file_non_owned_ = space->oat_file_.get();1383    } else {1384      space->oat_file_non_owned_ = oat_file;1385    }...1431    return space.release();1432  }

传入的参数oat_file为空,所以会走space->OpenOatFile()去打开和加载对应的oat文件。

1434  OatFile* ImageSpace::OpenOatFile(const char* image_path, std::string* error_msg) const {1435    const ImageHeader& image_header = GetImageHeader();1436    std::string oat_filename = ImageHeader::GetOatLocationFromImageLocation(image_path);1437  1438    CHECK(image_header.GetOatDataBegin() != nullptr);1439  1440    OatFile* oat_file = OatFile::Open(oat_filename,  //打开oat文件,将它加载到内存对应位置1441                                      oat_filename,1442                                      image_header.GetOatDataBegin(),1443                                      image_header.GetOatFileBegin(),1444                                      !Runtime::Current()->IsAotCompiler(),1445                                      /*low_4gb*/false,1446                                      nullptr,1447                                      error_msg);1448    if (oat_file == nullptr) {1449      *error_msg = StringPrintf("Failed to open oat file '%s' referenced from image %s: %s",1450                                oat_filename.c_str(), GetName(), error_msg->c_str());1451      return nullptr;1452    }1453    uint32_t oat_checksum = oat_file->GetOatHeader().GetChecksum();1454    uint32_t image_oat_checksum = image_header.GetOatChecksum();1455    if (oat_checksum != image_oat_checksum) { //art文件中有对应oat文件的checksum信息,根据checksum判断文件是否一致1456      *error_msg = StringPrintf("Failed to match oat file checksum 0x%x to expected oat checksum 0x%x"1457                                " in image %s", oat_checksum, image_oat_checksum, GetName());1458      return nullptr;1459    }1469    return oat_file;1470  }


oat被加载的位置是固定的。art文件会指定这个位置,这样art文件 就可以和对应的oat文件关联起来了,关于art和oat文件的结构,后面再介绍吧。




原创粉丝点击