Android ART虚拟机 堆Heap类构造函数

前言

本文主要介绍Heap的构造函数,从构造函数里大量使用各种Space,可以看出ART虚拟机的一个重要的特点就是大量使用映射内存。主要代码在art/runtime/gc/heap.cc里。

第一部分

主要完成了boot镜像所需art文件的加载,然后得到一系列的ImageSpace对象,最后再保存到Heap对应的成员变量中。

static const char* kDlMallocSpaceName[2] = {
    
    "main dlmalloc space", "main dlmalloc space 1"};
static const char* kRosAllocSpaceName[2] = {
    
    "main rosalloc space", "main rosalloc space 1"};
static const char* kMemMapSpaceName[2] = {
    
    "main space", "main space 1"};
static const char* kNonMovingSpaceName = "non moving space";
static const char* kZygoteSpaceName = "zygote space";

Heap::Heap(size_t initial_size.....)
  :max_allowed_footprint_(initial_size), 
   native_footprint_gc_watermark_(initial_size),
      foreground_collector_type_(foreground_collector_type),
      background_collector_type_(background_collector_type),
      desired_collector_type_(foreground_collector_type_),
   ...{
    
    

  Runtime* const runtime = Runtime::Current();
  // 设置垃圾回收器类型
  ChangeCollector(desired_collector_type_);
  // 初始化两个bitmap
  live_bitmap_.reset(new accounting::HeapBitmap(this));
  mark_bitmap_.reset(new accounting::HeapBitmap(this));

  // 加载ImageSpace,
  // 主要完成了boot镜像所需art文件的加载,然后得到一系列的ImageSpace对象,最后再保存到Heap对应的成员变量中
  if (!image_file_name.empty()) {
    
    
    std::vector<std::string> image_file_names;
    image_file_names.push_back(image_file_name);
    // The loaded spaces. Secondary images may fail to load, in which case we need to remove already added spaces.
    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];
      std::string error_msg;
      space::ImageSpace* boot_image_space = space::ImageSpace::CreateBootImage(
          image_name.c_str(),
          image_instruction_set,
          index > 0,
          &error_msg);
      if (boot_image_space != nullptr) {
    
    
        // Oat files referenced by image files immediately follow them in memory, ensure alloc space isn't going to get in the middle

        // 将boot_image_space保存到heap对应的管理模块中
        AddSpace(boot_image_space);
        added_image_spaces.push_back(boot_image_space);

        // oat文件
        uint8_t* oat_file_end_addr = boot_image_space->GetImageHeader().GetOatFileEnd();
        requested_alloc_space_begin = AlignUp(oat_file_end_addr, kPageSize);
        // heap里的成员变量,保存art文件对应的ImageSpace对象
        boot_image_spaces_.push_back(boot_image_space);
        // ...
      }
  }

第二部分

主要创建各种Space,各种Space类下篇介绍;
构造函数里初始化的重要参数解释如下:

  • foreground_collector_type:当应用程序处于前台(即用户能感知的情况)时GC的类型。此处为kCollectorTypeCMS(以后简称CMS)
  • background_collector_type:当应用程序位于后台时GC的类型。此处为kCollectorTypeHomogeneousSpaceCompact (以后简称HSC)。注意,这是一种空间压缩的方法,可减少内存碎片。但需要较长时间暂停程序的运行,所以只能在程序位于后台(用户不可见)的时候来执行。
  • non_moving_space_capacity: 对应runtime_options.def中的NonMovingSpaceCapacity参数,默认取值为Heap.h文件中的kDefaultNonMovingSpaceCapacity(64MB)。
  • large_0bject_space_type参数,x86平台上其取值为kMap
  • large_object_threshold参数,默认取值为Heap.h的kDefaultLargeObjectThreshold(大小为3个内存页,此处为12K B)。
  • initial_size:取自dalvik.vm.heapstartsize
  • capacity,取自dalvik.vm.heapsize
  • growth_limit:取自dalvik.vm.heapgrowthlimit
  bool support_homogeneous_space_compaction =
      background_collector_type_ == gc::kCollectorTypeHomogeneousSpaceCompact ||
      use_homogeneous_space_compaction_for_oom_;

  std::unique_ptr<MemMap> main_mem_map_1;
  std::unique_ptr<MemMap> main_mem_map_2;

  uint8_t* request_begin = requested_alloc_space_begin;
  if (request_begin != nullptr && separate_non_moving_space) {
    
    
    request_begin += non_moving_space_capacity;  // +64M
  }

  std::unique_ptr<MemMap> non_moving_space_mem_map;
  if (separate_non_moving_space) {
    
    
    const char* space_name = is_zygote ? kZygoteSpaceName: kNonMovingSpaceName;
    // Reserve the non moving mem map before the other two since it needs to be at a specific address.
    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));

    // Try to reserve virtual memory at a lower address if we have a separate non moving space.
    request_begin = reinterpret_cast<uint8_t*>(300 * MB); // 0x12C00000
  }

  // kMemMapSpaceName[0]值为main_space,大小为capacity,内存地址从0x12C00000开始
  if (foreground_collector_type_ != kCollectorTypeCC) {
    
    
    if (separate_non_moving_space || !is_zygote) {
    
    
      main_mem_map_1.reset(MapAnonymousPreferredAddress(kMemMapSpaceName[0], request_begin, capacity_, &error_str));
    } else {
    
    
      // If no separate non-moving space and we are the zygote, the main space must come right after the image space to avoid a gap. This is required since we want the zygote space to be adjacent to the image space.
      main_mem_map_1.reset(MemMap::MapAnonymous(kMemMapSpaceName[0], request_begin, capacity_, PROT_READ | PROT_WRITE, true, false, &error_str));
    }
  }

  // kMemMapSpaceName[1]值为main space 1,Create main mem map 2,内存地址紧跟main space
  if (support_homogeneous_space_compaction || background_collector_type_ == kCollectorTypeSS || foreground_collector_type_ == kCollectorTypeSS) {
    
    
    main_mem_map_2.reset(MapAnonymousPreferredAddress(kMemMapSpaceName[1], main_mem_map_1->End(), capacity_, &error_str));
  }

  // Create the non moving space first so that bitmaps don't take up the address range. 是一个DlMallocSpace
  if (separate_non_moving_space) {
    
    
    const size_t size = non_moving_space_mem_map->Size();  // 默认为64M
    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_->SetFootprintLimit(non_moving_space_->Capacity());
    AddSpace(non_moving_space_);
  }

  // Create other spaces based on whether or not we have a moving GC.
  if (foreground_collector_type_ == kCollectorTypeCC) {
    
    ...
  } else if (IsMovingGc(foreground_collector_type_) && foreground_collector_type_ != kCollectorTypeGSS) {
    
     ...
  } else {
    
    
    // 初始化成员变量main_space,根据kUseRosAlloc常量值判断use rosalloc/RosAllocSpace instead of dlmalloc/DlMallocSpace,并赋值给dlmalloc_space_或rosalloc_space_
    CreateMainMallocSpace(main_mem_map_1.release(), initial_size, growth_limit_, capacity_);
    AddSpace(main_space_);

    if (foreground_collector_type_ == kCollectorTypeGSS) {
    
    ...
    } else if (main_mem_map_2.get() != nullptr) {
    
    
      // 初始化成员变量main_space_backup_,Pointer to the space which becomes the new main space when we do homogeneous space compaction.
      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());
    }
  }

  // Allocate the large object space.
  if (large_object_space_type == space::LargeObjectSpaceType::kFreeList) {
    
    
    large_object_space_ = space::FreeListSpace::Create("free list large object space", nullptr, capacity_);
  } else if (large_object_space_type == space::LargeObjectSpaceType::kMap) {
    
    
    large_object_space_ = space::LargeObjectMapSpace::Create("mem map large object space");
  } else {
    
    
    // Disable the large object space by making the cutoff excessively large.
    large_object_threshold_ = std::numeric_limits<size_t>::max();
    large_object_space_ = nullptr;
  }
  if (large_object_space_ != nullptr) {
    
    
    AddSpace(large_object_space_);
  }


  // Remove the main backup space since it slows down the GC to have unused extra spaces.
  // 从堆管理中移除main_space_backup_
  if (main_space_backup_.get() != nullptr) {
    
    
    RemoveSpace(main_space_backup_.get());
  }

  // Allocate the card table.
  // Start at 64 KB, we can be sure there are no spaces mapped this low since the address range is reserved by the kernel.
  static constexpr size_t kMinHeapAddress = 4 * KB;
  card_table_.reset(accounting::CardTable::Create(reinterpret_cast<uint8_t*>(kMinHeapAddress), 4 * GB - kMinHeapAddress));

  if (HasBootImageSpace()) {
    
    
     // 为每一个ImageSpace创建一个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);
    }
  }

  // 创建RememberSet
  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);
  }

  num_bytes_allocated_.StoreRelaxed(0);

  // Mark stack that we reuse to avoid re-allocating the mark stack.
  // Allocation stack, new allocations go here so that we can do sticky mark bits. This enables us to use the live bitmap as the old mark bitmap.
  // Second allocation stack so that we can process allocation with the heap unlocked.
  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相关;

  • 回收器类型为CMS时,前台回收器类型为CMS,后台回收器类型为HSC。garbage_collectors_包含四个回收器对象,分别是MarkSweep、PartialMarkSweep、StickyMarkSweep和SemiSpace。其中,前三个回收器启用concurrent gc功能,而SemiSpace关闭分代gc的功能。
  • 回收器类型为SS时,前台回收器类型为SS,后台回收器类型为HSC,garbage_collectors_包含一个SemiSpace回收器对象(关闭分代gc功能,generational为false)。
  • 回收器类型为GSS时,前后台都使用GSS回收器,garbage_collectors_包含一个SemiSpace回收器对象,启用分代gc的功能(generational为true)。
  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_));
  task_processor_.reset(new TaskProcessor());
  reference_processor_.reset(new ReferenceProcessor());
  pending_task_lock_ = new Mutex("Pending task lock");

  // Create our garbage collectors.
  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) {
    
    
    if (MayUseCollector(kCollectorTypeSS) || MayUseCollector(kCollectorTypeGSS) ||
        MayUseCollector(kCollectorTypeHomogeneousSpaceCompact) ||
        use_homogeneous_space_compaction_for_oom_) {
    
    
      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)) {
    
    
      concurrent_copying_collector_ = new collector::ConcurrentCopying(this);
      garbage_collectors_.push_back(concurrent_copying_collector_);
    }
    if (MayUseCollector(kCollectorTypeMC)) {
    
    
      mark_compact_collector_ = new collector::MarkCompact(this);
      garbage_collectors_.push_back(mark_compact_collector_);
    }
  }

}

bool Heap::MayUseCollector(CollectorType type) const {
    
    
  return foreground_collector_type_ == type || background_collector_type_ == type;
}

其他方法

addSpace

  • 如果是连续内存地址的Space对象,则将其加入continuous_spaces_数组中。该数组元素按照内存地址的起始位置由小到大排列。如果这个Space对象有live_bitmap_和mark_bitmap_位图对象,则对应将其加入Heap的live_bitmap_和mark_bitmap_的管理。
  • 如果是内存地址不连续的Space对象,则将其加入discontinuous_spaces_数组。没有排序的要求。如果这个Space对象内有live_bitmap_和mark_bitmap_位图对象,则对应将其加入Heap的live_bitmap_和mark_bitmap_的管理。
  • 如果是可分配内存的Space对象,则将其加入alloc_spaces_数组。
void Heap::AddSpace(space::Space* space) {
    
    
  WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
  if (space->IsContinuousSpace()) {
    
    
    space::ContinuousSpace* continuous_space = space->AsContinuousSpace();
    // Continuous spaces don't necessarily have bitmaps.
    // ContinuousSpace默认实现为ContinuousMemmapSpace,定义了live_bitmap、mark_bitmap这两成员变量;但只有DlMallocSpace和RosAllocSpace初始化了这俩。
    accounting::ContinuousSpaceBitmap* live_bitmap = continuous_space->GetLiveBitmap();
    accounting::ContinuousSpaceBitmap* mark_bitmap = continuous_space->GetMarkBitmap();
    if (live_bitmap != nullptr) {
    
    
      // 受管理
      live_bitmap_->AddContinuousSpaceBitmap(live_bitmap);
      mark_bitmap_->AddContinuousSpaceBitmap(mark_bitmap);
    }
    continuous_spaces_.push_back(continuous_space);

    // Ensure that spaces remain sorted in increasing order of start address.
    // 内存空间起始小的排在前面
    std::sort(continuous_spaces_.begin(), continuous_spaces_.end(), [](const space::ContinuousSpace* a, const space::ContinuousSpace* b) {
    
    
      return a->Begin() < b->Begin();
    });
  } else {
    
    
    space::DiscontinuousSpace* discontinuous_space = space->AsDiscontinuousSpace();
    live_bitmap_->AddLargeObjectBitmap(discontinuous_space->GetLiveBitmap());
    mark_bitmap_->AddLargeObjectBitmap(discontinuous_space->GetMarkBitmap());
    discontinuous_spaces_.push_back(discontinuous_space);
  }
  if (space->IsAllocSpace()) {
    
    
    alloc_spaces_.push_back(space->AsAllocSpace());
  }
}

RemoveSpace

RemoveSpace用于从上述管理模块中移除一个Space对象。

void Heap::RemoveSpace(space::Space* space) {
    
    
  WriterMutexLock mu(Thread::Current(), *Locks::heap_bitmap_lock_);
  if (space->IsContinuousSpace()) {
    
    
    space::ContinuousSpace* continuous_space = space->AsContinuousSpace();
    // Continuous spaces don't necessarily have bitmaps.
    accounting::ContinuousSpaceBitmap* live_bitmap = continuous_space->GetLiveBitmap();
    accounting::ContinuousSpaceBitmap* mark_bitmap = continuous_space->GetMarkBitmap();
    if (live_bitmap != nullptr) {
    
    
      live_bitmap_->RemoveContinuousSpaceBitmap(live_bitmap);
      mark_bitmap_->RemoveContinuousSpaceBitmap(mark_bitmap);
    }
    auto it = std::find(continuous_spaces_.begin(), continuous_spaces_.end(), continuous_space);
    continuous_spaces_.erase(it);
  } else {
    
    
    space::DiscontinuousSpace* discontinuous_space = space->AsDiscontinuousSpace();
    live_bitmap_->RemoveLargeObjectBitmap(discontinuous_space->GetLiveBitmap());
    mark_bitmap_->RemoveLargeObjectBitmap(discontinuous_space->GetMarkBitmap());
    auto it = std::find(discontinuous_spaces_.begin(), discontinuous_spaces_.end(), discontinuous_space);
    discontinuous_spaces_.erase(it);
  }
  if (space->IsAllocSpace()) {
    
    
    auto it = std::find(alloc_spaces_.begin(), alloc_spaces_.end(), space->AsAllocSpace());
    alloc_spaces_.erase(it);
  }
}

猜你喜欢

转载自blog.csdn.net/u014099894/article/details/129904592