(八) MarkSweep 垃圾清理

垃圾对象的内存释放,这项工作由ReclaimPhase完成。gc线程执行ReclaimPhase时,mutator线程可以同时运行。

void MarkSweep::ReclaimPhase() {
  TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings());
  Thread* const self = Thread::Current();
  // Process the references concurrently.
  ProcessReferences(self);
  SweepSystemWeaks(self);
  Runtime* const runtime = Runtime::Current();
  runtime->AllowNewSystemWeaks();
  // Clean up class loaders after system weaks are swept since that is how we know if class
  // unloading occurred.
  runtime->GetClassLinker()->CleanupClassLoaders();
  {
    WriterMutexLock mu(self, *Locks::heap_bitmap_lock_);
    GetHeap()->RecordFreeRevoke();
    // Reclaim unmarked objects.
    Sweep(false);
    // Swap the live and mark bitmaps for each space which we modified space. This is an
    // optimization that enables us to not clear live bits inside of the sweep. Only swaps unbound
    // bitmaps.
    SwapBitmaps();
    // Unbind the live and mark bitmaps.
    GetHeap()->UnBindBitmaps();
  }
}

IsMarked返回为空,说明obj没有被标记,是垃圾对象

inline mirror::Object* MarkSweep::IsMarked(mirror::Object* object) {
  if (immune_spaces_.IsInImmuneRegion(object)) {
    return object;
  }
  if (current_space_bitmap_->HasAddress(object)) {
    return current_space_bitmap_->Test(object) ? object : nullptr;
  }
  return mark_bitmap_->Test(object) ? object : nullptr;
}



void MarkSweep::Sweep(bool swap_bitmaps) {
  TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings());
  // Ensure that nobody inserted items in the live stack after we swapped the stacks.
  CHECK_GE(live_stack_freeze_size_, GetHeap()->GetLiveStack()->Size());
  {
    TimingLogger::ScopedTiming t2("MarkAllocStackAsLive", GetTimings());
    // Mark everything allocated since the last GC as live so that we can sweep concurrently,
    // knowing that new allocations won't be marked as live.
    accounting::ObjectStack* live_stack = heap_->GetLiveStack();
    heap_->MarkAllocStackAsLive(live_stack);
    live_stack->Reset();
    DCHECK(mark_stack_->IsEmpty());
  }
  for (const auto& space : GetHeap()->GetContinuousSpaces()) {
    if (space->IsContinuousMemMapAllocSpace()) {
      space::ContinuousMemMapAllocSpace* alloc_space = space->AsContinuousMemMapAllocSpace();
      TimingLogger::ScopedTiming split(
          alloc_space->IsZygoteSpace() ? "SweepZygoteSpace" : "SweepMallocSpace",
          GetTimings());
      RecordFree(alloc_space->Sweep(swap_bitmaps));
    }
  }
  SweepLargeObjects(swap_bitmaps);
}


(1)清理阶段swap_bitmaps为false,不交换
(2) Sweep检查空间的live_bitmap_和mark_bitmap_。live_bitmap_存在而mark_bitmap_不存在的对象被认为是垃圾对象,从而被清除。清除调用DlMallocSpace或RosAllocSpace的FreeList函数。注意BumpPointerSpace和RegionSpace无法释放单个内存对象的空间,所以它们不能用于MarkSweepGC。

collector::ObjectBytePair ContinuousMemMapAllocSpace::Sweep(bool swap_bitmaps) {
  accounting::ContinuousSpaceBitmap* live_bitmap = GetLiveBitmap();
  accounting::ContinuousSpaceBitmap* mark_bitmap = GetMarkBitmap();
  // If the bitmaps are bound then sweeping this space clearly won't do anything.
  if (live_bitmap == mark_bitmap) {
    return collector::ObjectBytePair(0, 0);
  }
  SweepCallbackContext scc(swap_bitmaps, this);
//(1)
  if (swap_bitmaps) {
    std::swap(live_bitmap, mark_bitmap);
  }
//(2)
  // Bitmaps are pre-swapped for optimization which enables sweeping with the heap unlocked.
  accounting::ContinuousSpaceBitmap::SweepWalk(
      *live_bitmap, *mark_bitmap, reinterpret_cast<uintptr_t>(Begin()),
      reinterpret_cast<uintptr_t>(End()), GetSweepCallback(), reinterpret_cast<void*>(&scc));
  return scc.freed;
}

SwapBitmaps的作用其实很简单,就是交换集合Live和集合Mark在相关数据结构中对应的成员变量。集合Live包含了此次GC中搜索到的对象。显然,它们构成了集合Live第二部分的内容——即上一次GC后剩下的对象。注意,本次GC的剩余对象将作为下一次GC中集合Live的内容

void GarbageCollector::SwapBitmaps() {
  TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings());
  // Swap the live and mark bitmaps for each alloc space. This is needed since sweep re-swaps
  // these bitmaps. The bitmap swapping is an optimization so that we do not need to clear the live
  // bits of dead objects in the live bitmap.
  const GcType gc_type = GetGcType();
  for (const auto& space : GetHeap()->GetContinuousSpaces()) {
    // We never allocate into zygote spaces.
    if (space->GetGcRetentionPolicy() == space::kGcRetentionPolicyAlwaysCollect ||
        (gc_type == kGcTypeFull &&
         space->GetGcRetentionPolicy() == space::kGcRetentionPolicyFullCollect)) {
      if (space->GetLiveBitmap() != nullptr && !space->HasBoundBitmaps()) {
        CHECK(space->IsContinuousMemMapAllocSpace());
        space->AsContinuousMemMapAllocSpace()->SwapBitmaps();
      }
    }
  }
  for (const auto& disc_space : GetHeap()->GetDiscontinuousSpaces()) {
    disc_space->AsLargeObjectSpace()->SwapBitmaps();
  }
}

最后阶段FinishPhase清空mark_stack_。清空space的mark_bitmap_。

void MarkSweep::FinishPhase() {
  TimingLogger::ScopedTiming t(__FUNCTION__, GetTimings());
  CHECK(mark_stack_->IsEmpty());  // Ensure that the mark stack is empty.
  mark_stack_->Reset();
  Thread* const self = Thread::Current();
  ReaderMutexLock mu(self, *Locks::mutator_lock_);
  WriterMutexLock mu2(self, *Locks::heap_bitmap_lock_);
  heap_->ClearMarkedObjects();
}


©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容