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 }
阅读全文
0 0
- art heap创建流程
- ART中 MIR --> LIR --> 机器码 的流程
- ART世界探险(6) - 流程控制指令
- ART执行类方法解析流程
- Dalvik的JIT编译流程 & ART的dex2oat流程
- ART
- ART
- Heap,创建进程私有堆
- ART世界探险(19) - 优化编译器的编译流程
- ART世界探险(20) - Android N上的编译流程
- 【个人笔记四】ART系统执行类方法流程分析
- dvm,art模式下的dex文件加载流程
- ART运行时Java堆创建过程分析
- ART运行时Java堆创建过程分析
- ART运行时Compacting GC堆创建过程分析
- ART运行时Java堆创建过程分析
- ART运行时Compacting GC堆创建过程分析
- art虚拟机缓存文件创建patchoat进程的分析
- tcp wcf
- ECMAscript5 手册
- 使用cp、mv命令时不询问
- [libxml2]_[C/C++]_[高效输出XML大文件]
- 8属性操作
- art heap创建流程
- 指针数组,数组指针,函数指针,函数指针数组 ,指向函数指针数组的指针
- usaco
- 通过ONOSFW项目让Neutron使用ONOS作为SDN控制器(by quqi99)
- 傅立叶变换的一种理解方式
- 调用秒滴接口
- 求100~300间能被3整除的数的和。
- 从头开始开发一个vue幻灯片组件
- Java线程