参考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永远不会进行垃圾回收。
待续