kGcCauseHomogeneousSpaceCompact的触发和执行
执行gc cause 为kGcCauseHomogeneousSpaceCompact的入口函数为PerformHomogeneousSpaceCompact()。
1. 由Forground GC切换为Background GC,会调用DoPendingCollectorTransition()方法,代码如下:
void Heap::DoPendingCollectorTransition() { //desired_collector_type 被赋值为background_collector_type_ CollectorType desired_collector_type = desired_collector_type_; LOG(INFO) << "desired_collector_type_" << desired_collector_type_; // Launch homogeneous space compaction if it is desired. if (desired_collector_type == kCollectorTypeHomogeneousSpaceCompact) { //若应用程序运行在前台,则CareAboutPauseTimes()为true,运行在后台,则为false if (!CareAboutPauseTimes()) { PerformHomogeneousSpaceCompact(); } else { VLOG(gc) << "Homogeneous compaction ignored due to jank perceptible process state"; } } else { TransitionCollector(desired_collector_type); } }
2. 为对象分配内存失败时,调用AllocateInternalWithGc()方法先执行必要的gc再分配内存,在抛出OOM前的一种情况就是调用PerformHomogeneousSpaceCompact()方法进行一次同构空间压缩,再做最后的分配。
AllocateInternalWithGc()方法的流程图如下:

mirror::Object* Heap::AllocateInternalWithGc(Thread* self, AllocatorType allocator, size_t alloc_size, size_t* bytes_allocated, size_t* usable_size, size_t* bytes_tl_bulk_allocated, mirror::Class** klass) { ... ... ptr = TryToAllocate<true, true>(self, allocator, alloc_size, bytes_allocated, usable_size, bytes_tl_bulk_allocated); if (ptr == nullptr) { const uint64_t current_time = NanoTime(); switch (allocator) { case kAllocatorTypeRosAlloc: // Fall-through. case kAllocatorTypeDlMalloc: { if (use_homogeneous_space_compaction_for_oom_ && current_time - last_time_homogeneous_space_compaction_by_oom_ > min_interval_homogeneous_space_compaction_by_oom_) { last_time_homogeneous_space_compaction_by_oom_ = current_time; HomogeneousSpaceCompactResult result = PerformHomogeneousSpaceCompact(); ... ... } // If the allocation hasn't succeeded by this point, throw an OOM error. if (ptr == nullptr) { ThrowOutOfMemoryError(self, alloc_size, allocator); } return ptr; }
PerformHomogeneousSpaceCompact()过程
该函数调用heap类的compact()方法将Main Space的对象移动到Backup Space,然后交换这两个space,从而实现Main空间的压缩。堆空间结构图如下:

From Space指向的是Main Space,To Space指向的是Backup Space。


collector::GarbageCollector* Heap::Compact(space::ContinuousMemMapAllocSpace* target_space, space::ContinuousMemMapAllocSpace* source_space, GcCause gc_cause) { CHECK(kMovingCollector); if (target_space != source_space) { // Don't swap spaces since this isn't a typical semi space collection. semi_space_collector_->SetSwapSemiSpaces(false); semi_space_collector_->SetFromSpace(source_space); semi_space_collector_->SetToSpace(target_space); semi_space_collector_->Run(gc_cause, false); return semi_space_collector_; } else { CHECK(target_space->IsBumpPointerSpace()) << "In-place compaction is only supported for bump pointer spaces"; mark_compact_collector_->SetSpace(target_space->AsBumpPointerSpace()); mark_compact_collector_->Run(kGcCauseCollectorTransition, false); return mark_compact_collector_; } }
target_space != source_space,接下来会调用semi_space_collector->Run()方法执行GC。

浙公网安备 33010602011771号