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。

 

posted @ 2016-03-23 10:28  牧 天  阅读(671)  评论(0)    收藏  举报