Heap
的创建位于/art/runtime/runtime.cc
的Runtime::Init
方法中
bool Runtime::Init(RuntimeArgumentMap&& runtime_options_in) {
...
//-Xgc
XGcOption xgc_option = runtime_options.GetOrDefault(Opt::GcOption);
heap_ = new gc::Heap(runtime_options.GetOrDefault(Opt::MemoryInitialSize),//-Xms:8m
//-XX:HeapGrowthLimit:256m
runtime_options.GetOrDefault(Opt::HeapGrowthLimit),
//-XX:HeapMinFree:512k
runtime_options.GetOrDefault(Opt::HeapMinFree),
//-XX:HeapMaxFree:8m
runtime_options.GetOrDefault(Opt::HeapMaxFree),
//-XX:HeapTargetUtilization:0.75
runtime_options.GetOrDefault(Opt::HeapTargetUtilization),
//-XX:ForegroundHeapGrowthMultiplier
runtime_options.GetOrDefault(Opt::ForegroundHeapGrowthMultiplier),
//-Xmx:512m
runtime_options.GetOrDefault(Opt::MemoryMaximumSize),
//-XX:NonMovingSpaceCapacity
runtime_options.GetOrDefault(Opt::NonMovingSpaceCapacity),
//-Ximage:/system/framework/boot.art
runtime_options.GetOrDefault(Opt::Image),
//imgaeinstructionset,是一个extra_info,用来hook: null
runtime_options.GetOrDefault(Opt::ImageInstructionSet),
//-Xgc:kuseReadBarrier ? gc::kCollectorTypeCC : gc::kCollectorTypeDefault
xgc_option.collector_type_,
//-XX:BackgroundGC
runtime_options.GetOrDefault(Opt::BackgroundGc),
//-XX:LargeObjectSpace
runtime_options.GetOrDefault(Opt::LargeObjectSpace),
//-XX:LargeObjectThreshold
runtime_options.GetOrDefault(Opt::LargeObjectThreshold),
//-XX:ParallelGCThreads:0u
runtime_options.GetOrDefault(Opt::ParallelGCThreads),
//-XX:ConcGCThreads
runtime_options.GetOrDefault(Opt::ConcGCThreads),
//-XX:LowMemoryMode:false
runtime_options.Exists(Opt::LowMemoryMode),
//-XX:LongPauseLogThreshold
runtime_options.GetOrDefault(Opt::LongPauseLogThreshold),
//-XX:LongGCLogThreshold
runtime_options.GetOrDefault(Opt::LongGCLogThreshold),
//-XX:IgnoreMaxFootprint
runtime_options.Exists(Opt::IgnoreMaxFootprint),
//-XX:UseTLAB
runtime_options.GetOrDefault(Opt::UseTLAB),
//default false
xgc_option.verify_pre_gc_heap_,
//default kIsDebugBuild
xgc_option.verify_pre_sweeping_heap_,
//default false
xgc_option.verify_post_gc_heap_,
//default kIsDebugBuild
xgc_option.verify_pre_gc_rosalloc_,
// default false
xgc_option.verify_pre_sweeping_rosalloc_,
//default false
xgc_option.verify_post_gc_rosalloc_,
//default false
xgc_option.gcstress_,
//-XX:EnableHSpaceCompactForOOM
runtime_options.GetOrDefault(Opt::EnableHSpaceCompactForOOM),
//-XX:HspaceCompactForOOMMinIntervalMs
runtime_options.GetOrDefault(Opt::HSpaceCompactForOOMMinIntervalsMs));
...
}
一. 相关知识预热
1.1 Garbage Collection Type
垃圾回收的算法有多种,如MarkSweep-标记清楚算法,MarkCompact-标记整理算法,Copying-复制算法等等,之前的Dalvik一直使用的是MarkSweep算法,ART则在MarkSweep的基础上添加了对其他垃圾回收算法的支持,具体的算法可以通过-Xgc
指定,如果没有特别指定,则使用默认指定的:
// /art/smdline/cmdline_types.h
gc::CollectorType collector_type_ = kUseReadBarrier ?
// If RB is enabled (currently a build-time decision),
// use CC as the default GC.
gc::kCollectorTypeCC :
gc::kCollectorTypeDefault;
kUseReadBarrier
定义在/art/runtime/globals.h
#ifdef USE_BAKER_READ_BARRIER
static constexpr bool kUseBakerReadBarrier = true;
#else
static constexpr bool kUseBakerReadBarrier = false;
#endif
#ifdef USE_BROOKS_READ_BARRIER
static constexpr bool kUseBrooksReadBarrier = true;
#else
static constexpr bool kUseBrooksReadBarrier = false;
#endif
#ifdef USE_TABLE_LOOKUP_READ_BARRIER
static constexpr bool kUseTableLookupReadBarrier = true;
#else
static constexpr bool kUseTableLookupReadBarrier = false;
#endif
static constexpr bool kUseBakerOrBrooksReadBarrier = kUseBakerReadBarrier || kUseBrooksReadBarrier;
static constexpr bool kUseReadBarrier =
kUseBakerReadBarrier || kUseBrooksReadBarrier || kUseTableLookupReadBarrier;
kUseReadBarrier
根据三个编译宏决定true或false,只要这个三个编译宏中有一个存在,则kUseReadBarrier=true
gc::kCollectorTypeCC
和gc::kCollectorTypeDefault
定义在/art/runtime/gc/collector_type.h
enum CollectorType {
// No collector selected.
kCollectorTypeNone,
//普通Mark-Sweep
kCollectorTypeMS,
// 并发Mark-Sweep.
kCollectorTypeCMS,
// Semi-space和Mark-Sweep的混合
kCollectorTypeSS,
// Generational Semi-space
kCollectorTypeGSS,
// Mark compact
kCollectorTypeMC,
// Heap trimming collector, doesn't do any actual collecting.
kCollectorTypeHeapTrim,
// A (mostly) concurrent copying collector.
kCollectorTypeCC,
// Instrumentation critical section fake collector.
kCollectorTypeInstrumentation,
// Fake collector for adding or removing application image spaces.
kCollectorTypeAddRemoveAppImageSpace,
// A homogeneous space compaction collector used in background transition
// when both foreground and background collector are CMS.
kCollectorTypeHomogeneousSpaceCompact,
// Class linker fake collector.
kCollectorTypeClassLinker,
};
static constexpr CollectorType kCollectorTypeDefault =
#if ART_DEFAULT_GC_TYPE_IS_CMS
kCollectorTypeCMS
#elif ART_DEFAULT_GC_TYPE_IS_SS
kCollectorTypeSS
#elif ART_DEFAULT_GC_TYPE_IS_GSS
kCollectorTypeGSS
#else
kCollectorTypeCMS
#error "ART default GC type must be set"
#endif
从代码中的定义可以看到,如果kUseReadBarrier=true
,则垃圾回收算法使用Concurrent-Copying
,否则默认算法,默认算法根据编译宏选择,没有特别指定的情况下使用Concurrent Mark-Sweep
二. Heap::Heap()
2.1 构造函数声明
Heap(size_t initial_size,//堆的初始大小
size_t growth_limit,//堆的增长上限
size_t min_free,//堆的最小空闲值
size_t max_free,//堆的最大空闲值
double target_utilization,//堆的目标利用率
double foreground_heap_growth_multiplier,//前台堆增长因子(乘数)
size_t capacity,//堆的容量
size_t non_moving_space_capacity,//存储不可移动对象的space的容量
const std::string& original_image_file_name,//image文件路径
InstructionSet image_instruction_set,//指令集
CollectorType foreground_collector_type,//前台回收器类型
CollectorType background_collector_type,//后台回收器类型
space::LargeObjectSpaceType large_object_space_type,//存储大对象的space类型
size_t large_object_threshold,//大对象数量的阈值
size_t parallel_gc_threads,//GC暂停阶段用于同时执行GC任务的线程数
size_t conc_gc_threads,//并行GC的线程数
bool low_memory_mode,//是否是low memory mode
size_t long_pause_threshold,//GC造成应用程序暂停的时间阀值,超过则输出log
size_t long_gc_threshold,//GC时间阀值,超过则输出log
bool ignore_max_footprint,//不对堆的增长进行限制,堆可以增长到它的最大容量
bool use_tlab,//是否开启TLAB选项
bool verify_pre_gc_heap,//是否在开始GC前验证堆
bool verify_pre_sweeping_heap,//是否在GC执行清扫前验证堆
bool verify_post_gc_heap,//是否在GC完成清扫后验证堆
bool verify_pre_gc_rosalloc,//是否在开始GC前验证RosAllocSpace
bool verify_pre_sweeping_rosalloc,//是否在GC执行清扫前验证RosAllocSpace
bool verify_post_gc_rosalloc,//是否在GC完成清扫后验证RosAllocSpace
bool gc_stress_mode,
bool use_homogeneous_space_compaction,//是否使用homogeneous space compaction来避免OOM
uint64_t min_interval_homogeneous_space_compaction_by_oom);//两次OOM引起homogeneous space compaction时间间隔
2.2 构造函数实现
2.2.1 字段初始化
Heap::Heap(...) :
//space::MallocSpace*,存放不可移动对象
non_moving_space_(nullptr),
//kAllocatorTypeROSAlloc space
rosalloc_space_(nullptr),
//kAllocatorTypeDlMalloc space
dlmalloc_space_(nullptr),
//GC操作的主要space,这个space不是dlmalloc_space_就是rosalloc_space_
main_space_(nullptr),
//回收器类型
collector_type_(kCollectorTypeNone),
//前台回收器类型
foreground_collector_type_(foreground_collector_type),
//后台回收器类型
background_collector_type_(background_collector_type),
//希望的回收器类型,如果它!=collector_type_, heap trimming daemon会transitions堆
desired_collector_type_(foreground_collector_type_),
//Mutex*
pending_task_lock_(nullptr),
//GC暂停阶段用于同时执行GC任务的线程数
parallel_gc_threads_(parallel_gc_threads),
//concurrent gc线程数
conc_gc_threads_(conc_gc_threads),
//是否是低内存模式
low_memory_mode_(low_memory_mode),
//GC造成应用程序暂停的时间阀值,超过则输出log
long_pause_log_threshold_(long_pause_log_threshold),
//GC时间阀值,超过则输出log
long_gc_log_threshold_(long_gc_log_threshold),
//是否对堆的增长不限制
ignore_max_footprint_(ignore_max_footprint),
//zygote space创建时的锁, Mutex
zygote_creation_lock_("zygote creation lock", kZygoteCreationLock),
//space::ZygoteSpace 在zygote space创建之前不会包含大对象
zygote_space_(nullptr),
//大对象数量的阈值
large_object_threshold_(large_object_threshold),
//跟踪在JNI critical section中有多少个线程
disable_thread_flip_count_(0),
thread_flip_running_(false),
//正在运行的回收器类型
collector_type_running_(kCollectorTypeNone),
//最后一次运行的GC类型
last_gc_type_(collector::kGcTypeNone),
//下一次将要运行的GC类型
next_gc_type_(collector::kGcTypePartial),
//堆的容量
capacity_(capacity),
//堆的增长上限
growth_limit_(growth_limit),
//分配对象的上限数,一旦超过着搁置会引起一次GC
max_allowed_footprint_(initial_size),
//由registerNativeAllocation请求的一次concurrent GC需要的临界线, size_t
native_footprint_gc_watermark_(initial_size),
//bool, 是否需要在下一次的native allocation中运行finalizers
native_need_to_run_finalization_(false),
//当num_bytes_allocated_超过该值后,concurrent GC会启动
concurrent_start_bytes_(std::numeric_limits<size_t>::max()),
//总共释放的bytes自从heap创建以来
total_bytes_freed_ever_(0),
//总共释放的对象自从heap创建以来
total_objects_freed_ever_(0),
//当前分配的bytes数量.每次释放和分配以后都会更新
num_bytes_allocated_(0),
//native分配的bytes数量
native_bytes_allocated_(0),
//Mutex
native_histogram_lock_("Native allocation lock"),
//Histogram<uint64_t>,native分配的统计图
native_allocation_histogram_("Native allocation sizes",
1U,
kNativeAllocationHistogramBuckets),
//native释放的统计图
native_free_histogram_("Native free sizes", 1U, kNativeAllocationHistogramBuckets),
num_bytes_freed_revoke_(0),
verify_missing_card_marks_(false),
verify_system_weaks_(false),
//是否在开始GC前验证堆
verify_pre_gc_heap_(verify_pre_gc_heap),
//是否在GC执行清扫前验证堆
verify_pre_sweeping_heap_(verify_pre_sweeping_heap),
//是否在GC完成清扫后验证堆
verify_post_gc_heap_(verify_post_gc_heap),
//是否验证ModUnionTable
verify_mod_union_table_(false),
//是否在开始GC前验证RosAllocSpace
verify_pre_gc_rosalloc_(verify_pre_gc_rosalloc),
//是否在GC执行清扫前验证RosAllocSpace
verify_pre_sweeping_rosalloc_(verify_pre_sweeping_rosalloc),
//是否在GC完成清扫后验证RosAllocSpace
verify_post_gc_rosalloc_(verify_post_gc_rosalloc),
/* For GC a lot mode, we limit the allocations stacks to be kGcAlotInterval allocations. This
* causes a lot of GC since we do a GC for alloc whenever the stack is full. When heap
* verification is enabled, we limit the size of allocation stacks to speed up their
* searching.
*/
//分配栈最大数量
max_allocation_stack_size_(kGCALotMode ? kGcAlotAllocationStackSize
: (kVerifyObjectSupport > kVerifyObjectModeFast) ? kVerifyObjectAllocationStackSize :
kDefaultAllocationStackSize),
//当前分配器
current_allocator_(kAllocatorTypeDlMalloc),
//当前不可移动对象分配器
current_non_moving_allocator_(kAllocatorTypeNonMoving),
//阶跃型指针space
bump_pointer_space_(nullptr),
//临时space,Semispace回收器会将对象拷贝至这里
temp_space_(nullptr),
//RegionSpace 有一系列大小相等的区域组成
region_space_(nullptr),
//最小空余内存
min_free_(min_free),
//最大空余内存
max_free_(max_free),
//堆目标利用率
target_utilization_(target_utilization),
//前台堆增长因子
foreground_heap_growth_multiplier_(foreground_heap_growth_multiplier),
//mutators暂停等待GC的总共时间
total_wait_time_(0),
//VerifyObjectMode, 目前heap verification的状态
verify_object_mode_(kVerifyObjectModeDisabled),
//Compacting GC disable count
disable_moving_gc_count_(0),
is_running_on_memory_tool_(Runtime::Current()->IsRunningOnMemoryTool()),
use_tlab_(use_tlab),
//homogeneous space compaction时的新main space
main_space_backup_(nullptr),
//两次OOM引起homogeneous space compaction时间间隔
min_interval_homogeneous_space_compaction_by_oom_(
min_interval_homogeneous_space_compaction_by_oom),
//上一次由OOM引起的HomogeneousSpaceCompact的时间
last_time_homogeneous_space_compaction_by_oom_(NanoTime()),
//CollectorTransitionTask*
pending_collector_transition_(nullptr),
//HeapTrimTask*
pending_heap_trim_(nullptr),
//是否使用homogeneous space compaction来避免OOM
use_homogeneous_space_compaction_for_oom_(use_homogeneous_space_compaction_for_oom),
//如果当前的回收工作导致一些线程暂停,则该值为true
running_collection_is_blocking_(false),
//blocking gc 数量
blocking_gc_count_(0U),
//blocking gc总共持续时间
blocking_gc_time_(0U),
//GC count rate统计图最后已更新时间
last_update_time_gc_count_rate_histograms_( // Round down by the window duration.
(NanoTime() / kGcCountRateHistogramWindowDuration) * kGcCountRateHistogramWindowDuration),
//在上一个window运行的GC数量
gc_count_last_window_(0U),
//在上一个window运行的blocking GC数量
blocking_gc_count_last_window_(0U),
//每一个window的GC调用统计图
gc_count_rate_histogram_("gc count rate histogram", 1U, kGcCountRateMaxBucketCount),
//每一个window的blocking GC调用统计图
blocking_gc_count_rate_histogram_("blocking gc count rate histogram", 1U,
kGcCountRateMaxBucketCount),
//是否支持allocation tracking
alloc_tracking_enabled_(false),
//Mutex*
backtrace_lock_(nullptr),
seen_backtrace_count_(0u),
unique_backtrace_count_(0u),
gc_disabled_for_shutdown_(false) {
2.2.2 具体创建逻辑
Heap的构造函数的代码较多,不过整体逻辑比较清晰,整体逻辑可以分为以下几块:
- 判断当前是否在zygote进程,如果不在zygote,将
background_collector_type_
设为和foreground_collector_type_
一样,并检查传入的desired_collector_type_
和collector_type_
是否一样,如果不一样,则将collector_type_
设为desired_collector_type_
Runtime* const runtime = Runtime::Current();
//判断当前是否是zygote模式,如果不是判断后台回收器类型是否和前台回收器相等,不想等,则设为相等
const bool is_zygote = runtime->IsZygote();
if (!is_zygote) {
if (background_collector_type_ != foreground_collector_type_) {
...
background_collector_type_ = foreground_collector_type_;
}
}
//检查collector_type_是否和desired_collector_type_相等,不等的话将collector_type_置为desired_collector_type_
ChangeCollector(desired_collector_type_);
- 创建两个HeapBitmap(
live_bitmap_
:用来记录上次GC之后还存活的对象;mark_bitmap_
:用来记录当前GC中还存活的对象)
live_bitmap_.reset(new accounting::HeapBitmap(this));
mark_bitmap_.reset(new accounting::HeapBitmap(this));
- 如果
foreground_collector_type_
是Concurrent-Copying,设置requested_alloc_space_begin
即alloc space的起始地址为(如果前台回收器是CC则是300MB-non_moving_space_capacity,否则是nullptr)
if (foreground_collector_type_ == kCollectorTypeCC) {
...
requested_alloc_space_begin = reinterpret_cast<uint8_t*>(300 * MB) - non_moving_space_capacity;
}
- 根据传入的image文件路径(
/system/framework/boot.art
)创建ImageSpace,在ImageSpace后面紧跟的是/system/framework/boot.oat
,如果创建成功,将requested_alloc_space_begin
指向boot.oat地址的末尾;如果创建ImageSpace失败,删除已加载的Space,将requested_alloc_space_begin
指回原来的(300MB-non_moving_space_capacity)
//创建ImageSpace, image_file_name是/system/framework/boot.art
if (!image_file_name.empty()) {
std::vector<std::string> image_file_names;
image_file_names.push_back(image_file_name);
std::vector<space::Space*> added_image_spaces;
uint8_t* const original_requested_alloc_space_begin = requested_alloc_space_begin;
for (size_t index = 0; index < image_file_names.size(); ++index) {
std::string& image_name = image_file_names[index];///system/framework/boot.art
std::string error_msg;
//创建boot_image_space
space::ImageSpace* boot_image_space = space::ImageSpace::CreateBootImage(
image_name.c_str(),
image_instruction_set,
index > 0,
&error_msg);
//创建boot_image_space成功
if (boot_image_space != nullptr) {
/* 根据boot_image_space是否时连续空间,将boot_image_space添加到对应的Space列表,并在live_bitmap_和mark_bitmap_中添加对应的位图 */
AddSpace(boot_image_space);
added_image_spaces.push_back(boot_image_space);
//Oat文件即boot.oat紧跟在boot_image_space末尾
uint8_t* oat_file_end_addr = boot_image_space->GetImageHeader().GetOatFileEnd();
...
//将boot.oat的地址按页大小(pageSize)对齐
requested_alloc_space_begin = AlignUp(oat_file_end_addr, kPageSize);
boot_image_spaces_.push_back(boot_image_space);
if (index == 0) {
//如果是第一块Space,检查是否还有其他的oat文件需要加载
const OatFile* boot_oat_file = boot_image_space->GetOatFile();
if (boot_oat_file == nullptr) {
continue;
}
//如果还有其他的oat文件,根据OatHeader获取boot_classpath,再根据boot_classpath生成
//oat文件完整路径,将完整路径添加进image文件列表,从而可以在下次循环中加载
const OatHeader& boot_oat_header = boot_oat_file->GetOatHeader();
const char* boot_classpath =
boot_oat_header.GetStoreValueByKey(OatHeader::kBootClassPathKey);
if (boot_classpath == nullptr) {
continue;
}
space::ImageSpace::CreateMultiImageLocations(image_file_name,
boot_classpath,
&image_file_names);
}
} else {
//创建ImageSpace失败, 删除已加载的Space
for (space::Space* loaded_space : added_image_spaces) {
RemoveSpace(loaded_space);
delete loaded_space;
}
boot_image_spaces_.clear();
requested_alloc_space_begin = original_requested_alloc_space_begin;
break;
}
}
}
- 判断是否支持Homogeneous-Space-Compact.当
background_collector_type_
是Homogeneous-Space-Compact或者foreground_collector_type_
不是GSS(Generational Semi-Space)
和CC(Concurrent-Copying)
时,支持Homogeneous-Space-Compact
if (foreground_collector_type_ == kCollectorTypeGSS ||
foreground_collector_type_ == kCollectorTypeCC) {
use_homogeneous_space_compaction_for_oom_ = false;
}
//如果后台回收器是homogeneous space compact或者前台回收器不是GSS和CC时,支持homogeneous space compact
bool support_homogeneous_space_compaction =
background_collector_type_ == gc::kCollectorTypeHomogeneousSpaceCompact ||
use_homogeneous_space_compaction_for_oom_;
- 判断是否给Non-Moving Space独立的地址.只要以下满足四个条件中的一项就会给Non-Moving Space独立地址(处于Zygote;支持Homogeneous-Space-Compact(
foreground_collector_type_
不是GSS
或者不是CC
);foreground_collector_type_
可以移动对象;background_collector_type_
可以移动对象), 之后再排除foreground_collector_type_
是GSS的情况,即前台回收器是GSS时,不给Non-Moving Space独立地址
//如果当前处于Zygote模式或者支持homogeneous space compact或者前台回收器是可以移动对象的或者后台回收器也可以移动对象时
//给non_moving_space一个独立的地址
bool separate_non_moving_space = is_zygote ||
support_homogeneous_space_compaction || IsMovingGc(foreground_collector_type_) ||
IsMovingGc(background_collector_type_);
//再次检查前台进程是否是GSS,如果是,则不给non_moving_space_一个独立的地址
if (foreground_collector_type_ == kCollectorTypeGSS) {
separate_non_moving_space = false;
}
只要传入的type是SS,GSS,CC,MC,Homogeneous-Space-Compact其中一个时,
IsMovingGc
返回的都是true
- 创建两个内存映射
MemMap
std::unique_ptr<MemMap> main_mem_map_1;
std::unique_ptr<MemMap> main_mem_map_2;
- 如果之前创建ImageSpace失败同时
foreground_collector_type_
是MarkSweep
而且此时的Runtime由dex2oat创建即处于dex2oat进程中时,将requested_alloc_space_begin
指向kAllocSpaceBeginForDeterministicAoT
// 如果前台回收器是MS(MarkSweep)且requested_alloc_space_begin
// 是null(即之前ImageSpace创建失败)同时当前是dex2oat程序
// 将requested_alloc_space_begin设为kAllocSpaceBeginForDeterministicAoT
if (foreground_collector_type_ == kCollectorTypeMS &&
requested_alloc_space_begin == nullptr &&
Runtime::Current()->IsAotCompiler()) {
requested_alloc_space_begin = reinterpret_cast<uint8_t*>(kAllocSpaceBeginForDeterministicAoT);
}
- 初始化
request_begin
.如果Non-Moving Space有独立地址,根据当前是否是zygote确定Non-Moving Space的名字,之后创建一块匿名内存映射,由non_moving_space_mem_map
指向,non_moving_space_mem_map
紧跟在requested_alloc_space_begin
后面,如果ImageSpace创建成功,就是紧跟在ImageSpace+boot.oat后面,否则紧跟在kAllocSpaceBeginForDeterministicAoT
后面,最后设置request_begin
为300MB,即其他Space的起始地址为300MB
uint8_t* request_begin = requested_alloc_space_begin;
if (request_begin != nullptr && separate_non_moving_space) {
request_begin += non_moving_space_capacity;
}
std::string error_str;
std::unique_ptr<MemMap> non_moving_space_mem_map;
//如果确定给non moving space一块独立的地址
if (separate_non_moving_space) {
ScopedTrace trace2("Create separate non moving space");
// 如果当前正在Zygote当中,将non moving space设为zygote space
const char* space_name = is_zygote ? kZygoteSpaceName: kNonMovingSpaceName;
//创建匿名内存映射
//non moving sapce紧跟在requested_alloc_space_begin后面(即如果ImageSpace创建成功,紧跟在ImageSpace + boo.oat后面)
non_moving_space_mem_map.reset(
MemMap::MapAnonymous(space_name, requested_alloc_space_begin,
non_moving_space_capacity, PROT_READ | PROT_WRITE, true, false,
&error_str));
...
// 如果要给non moving space一个独立的地址, 将其他Space的起始地址设为300MB,由request_begin指向
request_begin = reinterpret_cast<uint8_t*>(300 * MB);
}
- 如果
foreground_collector_type_
不是CC
,初始化之前创造的main_mem_map_1
,这块内存的作用是作为MarkSweep
的Main Space或者Compact GC
的From-Bump-Space.当Non-Moving Space有独立地址且当前不处于Zygote时,紧跟在300MB后面创建匿名内存映射;否则紧跟在ImageSpace+boot.oat后面创建匿名内存映射
//如果前台回收器不是CC,创建第一块匿名共享内存,由main_mem_map_1指向,这块内存的作用是作为Compact GC的From Bump Space或者
//MarkSweep的Main Space
if (foreground_collector_type_ != kCollectorTypeCC) {
ScopedTrace trace2("Create main mem map");
if (separate_non_moving_space || !is_zygote) {
//如果non moving space有独立地址或者当前不是zygote,则main_mem_map_1紧跟在 request_begin后面,即300MB后面
//名字是main space
main_mem_map_1.reset(MapAnonymousPreferredAddress(kMemMapSpaceName[0],
request_begin,
capacity_,
&error_str));
} else {
//如果non-moving space有独立地址且当前处于zygote或者non-moving space没有独立地址,
//则main space必须紧跟在ImageSpace后面,这样zygote space就会临近ImageSpace
main_mem_map_1.reset(MemMap::MapAnonymous(kMemMapSpaceName[0], request_begin, capacity_,
PROT_READ | PROT_WRITE, true, false,
&error_str));
}
...
}
- 如果支持Homogeneous-Space-Compact或者
background_collector_type_
和foreground_collector_type_
其中一个是SS
时,创建第二块匿名内存映射main_mem_map_2
//如果支持homogeneous space compact或者后台回收器和前台回收器中有一个为为SS(Semi Space)时,创建第二块匿名共享内存
//由main_mem_map_2指向
if (support_homogeneous_space_compaction ||
background_collector_type_ == kCollectorTypeSS ||
foreground_collector_type_ == kCollectorTypeSS) {
ScopedTrace trace2("Create main mem map 2");
main_mem_map_2.reset(MapAnonymousPreferredAddress(kMemMapSpaceName[1], main_mem_map_1->End(),
capacity_, &error_str));
...
}
- 如果Non-Moving Space有独立地址,则之前已经创建了匿名内存映射
non_moving_space_mem_map
,现在将这块内存封装成DlMallocSpace
,由non-moving_space
指向,并将这块Space添加至Space列表中
//如果non moving space有独立的地址时,将non_moving_space_mem_map封装成Non-Moving Space(space::MallocSpace)
if (separate_non_moving_space) {
ScopedTrace trace2("Add non moving space");
//Non-Moving Space必须是dlmalloc,因为目前并不支持多个rosalloc spaces
const size_t size = non_moving_space_mem_map->Size();
non_moving_space_ = space::DlMallocSpace::CreateFromMemMap(
non_moving_space_mem_map.release(), "zygote / non moving space", kDefaultStartingSize,
initial_size, size, size, false);
//设置Non-Moving Space大小限制
non_moving_space_->SetFootprintLimit(non_moving_space_->Capacity());
...
//将non_moving_space_添加至space列表中
AddSpace(non_moving_space_);
}
- 根据条件处理之前创建的另外两块匿名内存映射
main_mem_map_1
和main_mem_map_2
.因为在之前的逻辑中,当foreground_collector_type_
是CC时,并没有创建main_mem_map_1
匿名内存映射,所以如果foreground_collector_type_
恰好是CC时,紧跟request_begin
(如果Non-Moving Space有独立地址,则是300MB,否则是ImageSpace+boot.oat)创建一个RegionSpace
,由region_space_
指向; 如果foreground_collector_type_
不是CC时,也要分两种情况:(1)foreground_collector_type_
是SS,MC,Homogeneous-Space-Compact
中的一个;(2)foreground_collector_type_
是MarkSweep, Compact MarkSweep
或者GSS
. 对于第一种情况来说,将main_mem_map_1
封装成BumpPointerSpace1
并添加至space列表,由bump_pointer_space_
指向,将main_mem_map_2
封装成另一块BumpPointerSpace2
同样添加至space列表,由temp_space_
指向;对于第二种情况,首先将main_mem_map_1
封装成MainSpace
同时添加至space列表,之后如果Non-Moving Space没有独立地址,则将non_moving_space_
指向MainSpace,即MainSpace和Non-Moving Space共用同一块内存,接着判断如果foreground_collector_type_是GSS时,调用BumpPointerSpace::Craete
直接创建BumpPointerSpace1
(bump_pointer_space_
)和BumpPointerSpace2
(temp_space_
)并依次添加至space列表;如果foreground_collector_type_
不是GSS
时,即MarkSweep
或Compact MarkSweep
,且main_mem_map_2
不为空时(如果支持HomogeneousSpaceCompact),将main_mem_map_2
封装成Backup Space
,并添加至space列表
if (foreground_collector_type_ == kCollectorTypeCC) {
// 如果前台回收器是CC(Concurrent Copying),创建RegionSpace,并将RegionSpace添加至space列表
region_space_ = space::RegionSpace::Create("Region space", capacity_ * 2, request_begin);
AddSpace(region_space_);
} else if (IsMovingGc(foreground_collector_type_) &&
foreground_collector_type_ != kCollectorTypeGSS) {
//如果前台回收器是除了GSS(Generational Semi-Space)以外的Compact GC,将main_mem_map_1封装成BumpPointerSpace
//并将bump_pointer_space_添加至space列表
// TODO: Place bump-pointer spaces somewhere to minimize size of card table.
bump_pointer_space_ = space::BumpPointerSpace::CreateFromMemMap("Bump pointer space 1",
main_mem_map_1.release());
...
AddSpace(bump_pointer_space_);
//将main_mem_map_2封装成第二块BumpPointerSpace,由temp_space_指向,同时将temp_space_添加至space列表
temp_space_ = space::BumpPointerSpace::CreateFromMemMap("Bump pointer space 2",
main_mem_map_2.release());
...
AddSpace(temp_space_);
...
} else {
//如果前台回收器不是Compact GC即MarkSweep或者是GSS,则在main_mem_map_1创建Main Space,并将Main Space添加至space列表
CreateMainMallocSpace(main_mem_map_1.release(), initial_size, growth_limit_, capacity_);
...
AddSpace(main_space_);
if (!separate_non_moving_space) {
//如果Non-Moving Space没有独立地址,则将non_moving_space_指向main_space_,即Non-Moving Space和Main Space是同一块Space
non_moving_space_ = main_space_;
...
}
if (foreground_collector_type_ == kCollectorTypeGSS) {
....
//如果前台回收器是GSS, 并创建BumpPointerSpace,由bump_pointer_space_指向
//同时将bump_pointer_space_添加至space列表
main_mem_map_2.release();
bump_pointer_space_ = space::BumpPointerSpace::Create("Bump pointer space 1",
kGSSBumpPointerSpaceCapacity, nullptr);
...
AddSpace(bump_pointer_space_);
//创建第二块BumpPointerSpace,由temp_space_指向,并将temp_space_添加至space列表
temp_space_ = space::BumpPointerSpace::Create("Bump pointer space 2",
kGSSBumpPointerSpaceCapacity, nullptr);
...
AddSpace(temp_space_);
} else if (main_mem_map_2.get() != nullptr) {
//此时前台回收器根据排除法只剩MarkSweep了,将main_mem_map_2封装成Backup Space,由main_space_backup_指向
//同时将main_space_backup_添加至space列表,如果kUseRosAlloc为true,main_space_backup_为RosAllocSpace,否则为DlMallocSpace
const char* name = kUseRosAlloc ? kRosAllocSpaceName[1] : kDlMallocSpaceName[1];
main_space_backup_.reset(CreateMallocSpaceFromMemMap(main_mem_map_2.release(), initial_size,
growth_limit_, capacity_, name, true));
...
AddSpace(main_space_backup_.get());
}
}
- 创建大对象存储空间.
// 创建LargeObjectSpace(大对象存储空间)
if (large_object_space_type == space::LargeObjectSpaceType::kFreeList) {
//如果LargeObjectSpace类型是FreeList,创建FreeList类型的LargeObjectSpace
large_object_space_ = space::FreeListSpace::Create("free list large object space", nullptr,
capacity_);
...
} else if (large_object_space_type == space::LargeObjectSpaceType::kMap) {
//创建相互独立的内存快组成的LargeObjectSpace
large_object_space_ = space::LargeObjectMapSpace::Create("mem map large object space");
...
} else {
large_object_threshold_ = std::numeric_limits<size_t>::max();
large_object_space_ = nullptr;
}
//如果LargeObjectSpace不为空,则添加至Space列表
if (large_object_space_ != nullptr) {
AddSpace(large_object_space_);
}
- 如果
foreground_collector_type_
是MarkSweep或Compact MarkSweep且创建了Backup Space
时,由于Backup Space占用的额外的空间会降低GC速度,所以移除Backup Space;之后创建CardTable
(Card Table是为了记录在垃圾收集过程中对象的引用情况的),ModUnionTable
(来记录ImageSpace对ZygoteSpace引用情况的ModUnionTable),RememberSet
(用来记录Non-moving Space对其他Space引用情况的RememberedSet,GSS
时不会创建,CC, SS, MC, HomogeneousSpaceCompact
时根据collector::SemiSpace::kUseRememberedSet == true
判断,MS,CMS
时根据Non-Moving Space有没有独立地址加collector::SemiSpace::kUseRememberedSet == true
判断)
//获取连续空间的起始地址和结束地址
uint8_t* heap_begin = continuous_spaces_.front()->Begin();
uint8_t* heap_end = continuous_spaces_.back()->Limit();
size_t heap_capacity = heap_end - heap_begin;
//移除main_space_backup_,此时foreground_collector_type_是MarkSweep
//因为Backup Space的额外的未使用的空间降低了GC速度
if (main_space_backup_.get() != nullptr) {
RemoveSpace(main_space_backup_.get());
}
...
// 创建card table,因为不知道在low_4gb模式下,app image会在何处定位,
// 所以card table将会从64KB开始覆盖整个4GB的低地址,64KB以前的地址预留给kernel
static constexpr size_t kMinHeapAddress = 4 * KB;
card_table_.reset(accounting::CardTable::Create(reinterpret_cast<uint8_t*>(kMinHeapAddress), 4 * GB - kMinHeapAddress));
....
//如果前台回收器是CC(Concurrent Copying)同时kUseTableLookupReadBarrier=true,创建ReadBarrierTable
if (foreground_collector_type_ == kCollectorTypeCC && kUseTableLookupReadBarrier) {
rb_table_.reset(new accounting::ReadBarrierTable());
...
}
if (HasBootImageSpace()) {
// 如果有ImageSpace,则创建用来记录ImageSpace对ZygoteSpace引用情况的ModUnionTable
for (space::ImageSpace* image_space : GetBootImageSpaces()) {
accounting::ModUnionTable* mod_union_table = new accounting::ModUnionTableToZygoteAllocspace(
"Image mod-union table", this, image_space);
...
AddModUnionTable(mod_union_table);
}
}
//如果Non-moving Space有独立地址而且kUseRememberedSet=true,
//创建用来记录Non-moving Space对其他Space引用情况的RememberedSet
if (collector::SemiSpace::kUseRememberedSet && non_moving_space_ != main_space_) {
accounting::RememberedSet* non_moving_space_rem_set =
new accounting::RememberedSet("Non-moving space remembered set", this, non_moving_space_);
...
AddRememberedSet(non_moving_space_rem_set);
}
- 创建
Mark-Stack
,Allocation-Stack
,Live-Stack
;创建之后GC需要用到的的锁;创建TaskProcessor
,ReferenceProcessor
;如果前后台回收器有一个是CMS,则创建一组包含三个支持并发的Collector:MarkSweep, PartialMarkSweep, StickyMarkSweep
回收器; 如果前后台回收器有一个是MS,则创建一组包含三个不支持并发的Collector:MarkSweep, PartialMarkSweep, StickyMarkSweep
回收器;之后再根据条件创建Semi-Space Collector
(SS
或GSS
时创建),Concurrent-Copying Collector
(CC
时创建),Mark Compact Collector
(MS,CMS
shichu)
// TODO: Count objects in the image space here?
num_bytes_allocated_.StoreRelaxed(0);
// 创建Mark-Stack, Allocation-Stack, Live-Stack
mark_stack_.reset(accounting::ObjectStack::Create("mark stack", kDefaultMarkStackSize, kDefaultMarkStackSize));
const size_t alloc_stack_capacity = max_allocation_stack_size_ + kAllocationStackReserveSize;
allocation_stack_.reset(accounting::ObjectStack::Create("allocation stack", max_allocation_stack_size_, alloc_stack_capacity));
live_stack_.reset(accounting::ObjectStack::Create("live stack", max_allocation_stack_size_, alloc_stack_capacity));
// 创建gc_complete_lock_,thread_flip_lock_
gc_complete_lock_ = new Mutex("GC complete lock");
gc_complete_cond_.reset(new ConditionVariable("GC complete condition variable",*gc_complete_lock_));
thread_flip_lock_ = new Mutex("GC thread flip lock");
thread_flip_cond_.reset(new ConditionVariable("GC thread flip condition variable",*thread_flip_lock_));
//创建TaskProcessor, ReferenceProcessor, pending_task_lock_
task_processor_.reset(new TaskProcessor());
reference_processor_.reset(new ReferenceProcessor());
pending_task_lock_ = new Mutex("Pending task lock");
if (ignore_max_footprint_) {
//如果不限制堆的增长,则将堆的最大限制数设为最大
SetIdealFootprint(std::numeric_limits<size_t>::max());
//将concurrent gc的启动值也设为最大,即只有堆达到最大时,才开启concurrent gc
concurrent_start_bytes_ = std::numeric_limits<size_t>::max();
}
...
// 如果前后台回收器有一个是CMS,则创建一组包含三个支持并发的Collector:MarkSweep, PartialMarkSweep, StickyMarkSweep回收器
// 如果前后台回收器有一个是MS,则创建一组包含三个不支持并发的Collector:MarkSweep, PartialMarkSweep, StickyMarkSweep回收器
for (size_t i = 0; i < 2; ++i) {
const bool concurrent = i != 0;
if ((MayUseCollector(kCollectorTypeCMS) && concurrent) ||
(MayUseCollector(kCollectorTypeMS) && !concurrent)) {
garbage_collectors_.push_back(new collector::MarkSweep(this, concurrent));
garbage_collectors_.push_back(new collector::PartialMarkSweep(this, concurrent));
garbage_collectors_.push_back(new collector::StickyMarkSweep(this, concurrent));
}
}
if (kMovingCollector) {//kMovingCollector=true
if (MayUseCollector(kCollectorTypeSS) || MayUseCollector(kCollectorTypeGSS) ||
MayUseCollector(kCollectorTypeHomogeneousSpaceCompact) ||
use_homogeneous_space_compaction_for_oom_) {
//如果前后台回收器中某一个是SS,GSS,HomogeneousSpaceCompact三者其中一个或者
//使用homogeneous space compaction来避免OOM时,再创键一个Semi-Space Collector
const bool generational = foreground_collector_type_ == kCollectorTypeGSS;
semi_space_collector_ = new collector::SemiSpace(this, generational,
generational ? "generational" : "");
garbage_collectors_.push_back(semi_space_collector_);
}
if (MayUseCollector(kCollectorTypeCC)) {
//如果前后台回收器中某一个是CC,再创建一个ConcurrentCopying Collector
concurrent_copying_collector_ = new collector::ConcurrentCopying(this);
garbage_collectors_.push_back(concurrent_copying_collector_);
}
if (MayUseCollector(kCollectorTypeMC)) {
//如果前后台回收器中某一个是MarkCompact,再创建一个MarkCompact Collector
mark_compact_collector_ = new collector::MarkCompact(this);
garbage_collectors_.push_back(mark_compact_collector_);
}
}
- 如果有ImageSpace同时Non-Moving Space不为空同时满足三个条件(处于zygote,Non-Moving Space有独立地址,前台回收器是GSS)中的一个时,检查ImageSpace和Non-Moving Space之间没有内存空隙
if (!GetBootImageSpaces().empty() && non_moving_space_ != nullptr &&
(is_zygote || separate_non_moving_space || foreground_collector_type_ == kCollectorTypeGSS)) {
//如果有ImageSpace同时Non-Moving Space不为空同时满足三个条件
//(处于zygote,Non-Moving Space有独立地址,前台回收器是GSS)中的一个时,
//检查ImageSpace和Non-Moving Space只见没有内存空隙
space::ImageSpace* first_space = nullptr;
for (space::ImageSpace* space : boot_image_spaces_) {
if (first_space == nullptr || space->Begin() < first_space->Begin()) {
first_space = space;
}
}
bool no_gap = MemMap::CheckNoGaps(first_space->GetMemMap(), non_moving_space_->GetMemMap());
if (!no_gap) {
PrintFileToLog("/proc/self/maps", LogSeverity::ERROR);
MemMap::DumpMaps(LOG(ERROR), true);
...
}
}
instrumentation::Instrumentation* const instrumentation = runtime->GetInstrumentation();
if (gc_stress_mode_) {
backtrace_lock_ = new Mutex("GC complete lock");
}
if (is_running_on_memory_tool_ || gc_stress_mode_) {
instrumentation->InstrumentQuickAllocEntryPoints();
}
三. 总结
3.1 前台回收器是ConcurrentCopying
从代码逻辑看,如果foreground_collector_type_=kCollectorTypeCC
时Heap的创建流程要跟其他回收器类型的创建流程不太相同:
requested_alloc_space_begin = 300MB - non_moving_space_capacity
- 创建ImageSpace(只要image文件不为空,都会创建),如果创建成功,
requested_alloc_space_begin=ImageSpace+boo.oat
这一点所有回收器类型都一样,不同的是,如果创建失败,
requested_alloc_space_begin = 300MB - non_moving_space_capacity
, 其他回收器类型则是requested_alloc_space_begin = nullptr
- 如果
background_collector_type_ != kCollectorTypeHomogeneousSpaceCompact
,则不支持Homogeneous-Space-Compact
- 由于是
CC
回收器,所以必然会给Non-Moving Space独立的地址 - 由于是
CC
回收器,所以即使ImageSpace创建失败,requested_alloc_space_begin
也不会为nullptr
,又因为Non-Moving Space有独立的地址,所以最后request_begin=requested_alloc_space_begin + non_moving_space_capacity
如果ImageSpace创建成功,
request_begin=ImageSpace+boot.oat+non_moving_space_capacity
;如果创建失败,request_begin = 300MB-non_moving_space_capacity+non_moving_space_capacity
->request_begin=300MB
- 紧跟着
requested_alloc_space_begin
创建用于Non-Moving Space的匿名内存映射non_moving_space_mem_map
, 将request_begin
固定在300MB的地址(request_begin=reinterpret_cast<uint8_t*>(300*MB)
);之后将匿名内存映射封装成Non-Moving Space,如果在Zygote中,就叫ZygoteSpace
,否则叫Non-Moving Space
- 由于是
CC
回收器,所以不会创建两块匿名内存main_mem_map_1,main_mem_map_2
,而是紧跟着在request_begin
后(即300MB,因为之前已经将request_begin
固定在这个地址)直接创建RegionSpace
- 创建
LargeObjectSpace
- 如果
kUseTableLookupReadBarrier=true
,创建ReadBarrierTable
- 创建
CardTable
,ModUnionTable
(如果ImageSpace创建成功),如果collector::SemiSpace::kUseRememberedSet == true
创建RememberedSet
;创建allocation_stack_,mark_stack_,live_stack_
;创建锁;创建TaskProcessor,ReferenceProcessor
- 由于是
CC
回收器,创建collector::ConcurrentCopying
并添加至garbage_collectors_
- 如果ImageSpace创建成功,且Non-Moving Space不为空,检查ImageSpace和Non-Moving Space之间有没有内存间隙
因为是
CC
,所以Non-Moving Space必然有独立地址,所以只需要判断ImageSpace创建成功和Non-Moving Space不为空
3.2 前台回收器是GSS
GSS(Generational Semi-Space)是另一个较为特殊的回收器类型
requested_alloc_space_begin=nullptr
- 创建ImageSpace,如果成功,
requested_alloc_space_begin=ImageSpace+boot.oat
,如果创建失败,requested_alloc_space_begin=nullptr
- 如果
background_collector_type_ != kCollectorTypeHomogeneousSpaceCompact
,则肯定不支持Homogeneous-Space-Compact - 由于是
GSS
回收器,所以不会给Non-Moving Space独立的地址(这一点很重要,即不会创建Non-Moving Space的匿名内存映射) - 如果ImageSpace创建失败,则
request_begin=requested_alloc_space_begin=nullptr
;如果创建成功,则request_begin=reuqest_alloc_space_begin=ImageSpace+boo.oat
- 由于是
GSS
回收器,那么Non-Moving Space不会有独立地址,如果此时处于Zygote中,则紧跟ImageSpace+boo.oat创建匿名内存映射main_mem_map_1
(因为Non-Moving Space没有独立地址,所以不会将request_begin固定在300MB,又因为如果ImageSpace创建成功此时request_begin=ImageSpace+boot.oat) - 如果
background_collector_type_ == kCollectorTypeHomogeneousSpaceCompact
,则会紧跟着main_mem_map_1
再创建第二块匿名内存映射main_mem_map_2
,否则不会创建main_mem_map_2
- 将
main_mem_map_1
封装成Main Space
,由于是GSS
回收器,所以将non_moving_space_
也指向Main Space
- 由于是
GSS
回收器,调用space::BumpPointerSpace::Create
直接创建BumpPointerSpace1
和BumpPointerSpace2
- 创建
LargeObjectSpace
- 创建
CardTable
,ModUnionTable
(如果ImageSpace创建成功),由于是GSS
回收器,所以non_moving_space_ == main_space_
,所以不会创建RememberedSet
;创建allocation_stack_,mark_stack_,live_stack_
;创建锁;创建TaskProcessor,ReferenceProcessor
- 由于是
GSS
,所以创建collector::SemiSpace
,其中generational_ = true
- 如果ImageSpace创建成功,且
MainSpace
不为空,检查ImageSpace和Non-Moving Space之间有没有内存间隙
因为是
GSS
,所以non_moving_space_
指向MainSpace
,所以只需要判断ImageSpace创建成功和Non-Moving Space不为空
3.3 Moving GC(Semi-Space, MarkCompact, HomogeneousSpaceCompact)
requested_alloc_space_begin=nullptr
- 创建ImageSpace,如果成功,
requested_alloc_space_begin=ImageSpace+boot.oat
,如果创建失败,requested_alloc_space_begin=nullptr
- 由于不是
GSS
和CC
,所以只要传入的use_homogeneous_space_compaction==true
或者background_collector_type_ == kCollectorTypeHomogeneousSpaceCompact
时会支持Homogeneous-Space-Compact - Non-Moving必然有独立的地址
- 如果ImageSpace创建成功,
request_begin = requested_alloc_space_begin + non_moving_space_capacity
,否则request_begin=nullptr
- 创建Non-Moving Space使用的匿名内存映射
non_moving_space_mem_map
,将request_begin
固定在300MB的地址(request_begin=reinterpret_cast<uint8_t*>(300*MB)
) - 紧跟
request_begin
创建匿名内存映射main_mem_map_1
- 如果支持Homogeneous-Space-Compact或者前后台回收器有一个是
Semi-Space
,则紧跟main_mem_map_1
创建第二块匿名内存映射main_mem_map_2
- 将
non_moving_space_mem_map
封装成Non-Moving Space
,由non_moving_space_
指向 - 将
main_mem_map_1
封装成BumpPointerSpace1
,将main_mem_map_2
封装成BumpPointerSpace2
- 创建
LargeObjectSpace
- 创建
CardTable
,ModUnionTable
(如果ImageSpace创建成功),如果collector::SemiSpace::kUseRememberedSet == true
创建RememberedSet
;创建allocation_stack_,mark_stack_,live_stack_
;创建锁;创建TaskProcessor,ReferenceProcessor
- 如果前后台回收器中有一个是
SS
或Homogeneous-Space-Compact
,创建collector::SemiSpace
;如果前后台回收器有一个是MarkCompact
,则创建collector::MarkCompact
- 如果ImageSpace创建成功,且Non-Moving Space不为空,检查ImageSpace和Non-Moving Space之间有没有内存间隙
因为Non-Moving必然有独立的地址,所以只需要判断ImageSpace创建成功和Non-Moving Space不为空
3.4 前台回收器MarkSweep或Concurrent MarkSweep
requested_alloc_space_begin=nullptr
- 创建ImageSpace,如果成功,
requested_alloc_space_begin=ImageSpace+boot.oat
,如果创建失败,requested_alloc_space_begin=nullptr
- 由于不是
GSS
和CC
,所以只要传入的use_homogeneous_space_compaction=true
或者background_collector_type_ == kCollectorTypeHomogeneousSpaceCompact
时会支持Homogeneous-Space-Compact - 只要当前处于Zygote当中,则Non-Moving Space必然有独立地址,否则得看是否支持Homogeneous-Space-Compact,支持的话,就有独立地址,不支持就没有
- 如果ImageSpace创建失败且
foreground_collector_type_=kCollectorTypeMS
同时当前处于dex2oat,requested_alloc_space_begin=kAllocSpaceBeginForDeterministicAoT
- 如果ImageSpace创建成功且如果Non-Moving Space有独立地址的话,创建Non-Moving Space要用到的匿名内存映射
non_moving_space_mem_map
,将request_begin
固定在300MB的地址(request_begin=reinterpret_cast<uint8_t*>(300*MB)
) - 如果Non-Moving Space有独立地址或者当前不在Zygote中,紧跟着
request_begin
(300MB)创建匿名内存映射main_mem_map_1
;如果Non-Moving Space没有独立地址同时处于Zygote中,则紧跟着ImageSpace_boot.oat创建匿名内存映射main_mem_map_1
- 如果支持Homogeneous-Space-Compact,紧跟着
main_mem_map_1
创建第二块匿名内存映射main_mem_map_2
,否则不创建main_mem_map_2
- 如果Non-Moving Space有独立地址,将
non_moving_space_mem_map
封装成Non-Moving Space
- 将
main_mem_map_1
封装成Main Space
,如果Non-Moving Space没有独立地址,则将non_moving_space_
也指向MainSpace
- 如果之前创建了
main_mem_map_2
,则将main_mem_map_2
封装成Main Backup Space
- 创建
LargeObjectSpace
- 移除
Main Backup Space
- 创建
CardTable
,ModUnionTable
(如果ImageSpace创建成功),如果Non-Moving Space有独立地址,创建RememberedSet
,否则不创建;创建allocation_stack_,mark_stack_,live_stack_
;创建锁;创建TaskProcessor,ReferenceProcessor
- 创建一组回收器,里面有三个回收器分别是
MarkSweep, PartialMarkSweep, StickyMarkSweep
,如果是Concurrent Mark Compact
,则这一组回收器是支持并行GC的;如果是MarkSweep
,则这一组不支持并行GC - 如果ImageSpace创建成功且Non-Moving Space不为空同时满足:处于Zygote或者Non-Moving Space有独立地址时,检查ImageSpace和Non-Moving Space之间有没有内存间隙
因为Non-Moving Space有没有独立地址不确定,需要视条件而定