当前位置: 首页 > article >正文

Android ART虚拟机 GC的各种类型

前言

本文介绍ART虚拟机的GC类型,为下篇介绍ART的GC做准备。

GcRetentionPolicy

每个Space都有自己的gc回收策略,如下图所示:

  • kGcRetentionPolicyNeverCollect:不需要回收某个Space所包含的垃圾对象(因为该Space可能不存在垃圾对象)。
  • kGcRetentionPolicyAlwaysCollect:每次垃圾回收都需要处理某个Space空间。
  • kGcRetentionPolicyFullCollect:直到最后时刻才回收某个Space空间中的垃圾对象。这个最后时刻就是所谓的full GC。

image.png

垃圾收集器类型 和 内存分配器类型

各种头文件

art/runtime/gc/collector_type.h
art/runtime/gc/allocator_type.h
art/runtime/gc/gc_cause.h
art/runtime/gc/collector/garbage_collector.h

// Which types of collections are able to be performed.
enum CollectorType {
  // No collector selected.
  kCollectorTypeNone,
  // Non concurrent mark-sweep.
  kCollectorTypeMS,
  // Concurrent mark-sweep.
  kCollectorTypeCMS,
  // Semi-space / mark-sweep hybrid, enables compaction.
  kCollectorTypeSS,
  // A generational variant of kCollectorTypeSS.
  kCollectorTypeGSS,
  // Mark compact collector.
  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,
};

// Different types of allocators.
enum AllocatorType {
  kAllocatorTypeBumpPointer,  // Use BumpPointer allocator, has entrypoints.
  kAllocatorTypeTLAB,  // Use TLAB allocator, has entrypoints.
  kAllocatorTypeRosAlloc,  // Use RosAlloc allocator, has entrypoints.
  kAllocatorTypeDlMalloc,  // Use dlmalloc allocator, has entrypoints.
  kAllocatorTypeNonMoving,  // Special allocator for non moving objects, doesn't have entrypoints.
  kAllocatorTypeLOS,  // Large object space, also doesn't have entrypoints.
  kAllocatorTypeRegion,
  kAllocatorTypeRegionTLAB,
};

// What caused the GC?
enum GcCause {
  // GC triggered by a failed allocation. Thread doing allocation is blocked waiting for GC before
  // retrying allocation.
  kGcCauseForAlloc,
  // A background GC trying to ensure there is free memory ahead of allocations.
  kGcCauseBackground,
  // An explicit System.gc() call.
  kGcCauseExplicit,
  // GC triggered for a native allocation.
  kGcCauseForNativeAlloc,
  // GC triggered for a collector transition.
  kGcCauseCollectorTransition,
  // Not a real GC cause, used when we disable moving GC (currently for GetPrimitiveArrayCritical).
  kGcCauseDisableMovingGc,
  // Not a real GC cause, used when we trim the heap.
  kGcCauseTrim,
  // Not a real GC cause, used to implement exclusion between GC and instrumentation.
  kGcCauseInstrumentation,
  // Not a real GC cause, used to add or remove app image spaces.
  kGcCauseAddRemoveAppImageSpace,
  // GC triggered for background transition when both foreground and background collector are CMS.
  kGcCauseHomogeneousSpaceCompact,
  // Class linker cause, used to guard filling art methods with special values.
  kGcCauseClassLinker,
};

虚拟机启动时gc参数解析设置前后台回收器类型

oreground_collector_type_和background_collector_type_表示进程处于前台(即用户能感知)以及进程处于后台时的回收器类型。

  • 前台回收器为CMS时,后台回收器为HSC。
  • 前台回收器为SS时,后台回收器类型为HSC。
  • 前台回收器类型为GSS时,后台回收器类型也必须为GSS。

art/runtime/parsed_options.cc

bool ParsedOptions::DoParse(const RuntimeOptions& options,
                            bool ignore_unrecognized,
                            RuntimeArgumentMap* runtime_options) {

  {
    // If not set, background collector type defaults to homogeneous compaction.
    // If foreground is GSS, use GSS as background collector.
    // If not low memory mode, semispace otherwise.

    gc::CollectorType background_collector_type_;
    gc::CollectorType collector_type_ = (XGcOption{}).collector_type_;  // NOLINT [whitespace/braces] [5]
    bool low_memory_mode_ = args.Exists(M::LowMemoryMode);

    background_collector_type_ = args.GetOrDefault(M::BackgroundGc);
    {
      XGcOption* xgc = args.Get(M::GcOption);
      if (xgc != nullptr && xgc->collector_type_ != gc::kCollectorTypeNone) {
        collector_type_ = xgc->collector_type_;
      }
    }

    if (background_collector_type_ == gc::kCollectorTypeNone) {
      if (collector_type_ != gc::kCollectorTypeGSS) {
        background_collector_type_ = low_memory_mode_ ?
            gc::kCollectorTypeSS : gc::kCollectorTypeHomogeneousSpaceCompact;
      } else {
        background_collector_type_ = collector_type_;
      }
    }

    args.Set(M::BackgroundGc, BackgroundGcOption { background_collector_type_ });
  }
}

Heap构造函数根据回收器类型设置垃圾收集器

  • 回收器类型为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;
}

ChangeCollector设置gc_plan_

  • 如果回收器类型为CMS,则gc_plan_依次为kGcTypeSticky、kGcTypePartial和kGc-TypeFull。
  • 如果回收器类型为SS或GSS,则gc_plan_只有kGcTypeFull一种策略。
// Change the collector to be one of the possible options (MS, CMS, SS).
void Heap::ChangeCollector(CollectorType collector_type) {
  if (collector_type != collector_type_) {
    collector_type_ = collector_type;
    gc_plan_.clear();
    switch (collector_type_) {
      case kCollectorTypeCC: {
        gc_plan_.push_back(collector::kGcTypeFull);
        if (use_tlab_) {
          ChangeAllocator(kAllocatorTypeRegionTLAB);
        } else {
          ChangeAllocator(kAllocatorTypeRegion);
        }
        break;
      }
      case kCollectorTypeMC:  // Fall-through.
      case kCollectorTypeSS:  // Fall-through.
      case kCollectorTypeGSS: {
        gc_plan_.push_back(collector::kGcTypeFull);
        if (use_tlab_) {
          ChangeAllocator(kAllocatorTypeTLAB);
        } else {
          ChangeAllocator(kAllocatorTypeBumpPointer);
        }
        break;
      }
      case kCollectorTypeMS: {
        gc_plan_.push_back(collector::kGcTypeSticky);
        gc_plan_.push_back(collector::kGcTypePartial);
        gc_plan_.push_back(collector::kGcTypeFull);
        ChangeAllocator(kUseRosAlloc ? kAllocatorTypeRosAlloc : kAllocatorTypeDlMalloc);
        break;
      }
      case kCollectorTypeCMS: {
        gc_plan_.push_back(collector::kGcTypeSticky);
        gc_plan_.push_back(collector::kGcTypePartial);
        gc_plan_.push_back(collector::kGcTypeFull);
        ChangeAllocator(kUseRosAlloc ? kAllocatorTypeRosAlloc : kAllocatorTypeDlMalloc);
        break;
      }
      default: {
        UNIMPLEMENTED(FATAL);
        UNREACHABLE();
      }
    }
    if (IsGcConcurrent()) {
      concurrent_start_bytes_ =
          std::max(max_allowed_footprint_, kMinConcurrentRemainingBytes) - kMinConcurrentRemainingBytes;
    } else {
      concurrent_start_bytes_ = std::numeric_limits<size_t>::max();
    }
  }
}

// Change the allocator, updates entrypoints.
void Heap::ChangeAllocator(AllocatorType allocator) {
  if (current_allocator_ != allocator) {
    current_allocator_ = allocator;
    MutexLock mu(nullptr, *Locks::runtime_shutdown_lock_);
    SetQuickAllocEntryPointsAllocator(current_allocator_);
    Runtime::Current()->GetInstrumentation()->ResetQuickAllocEntryPoints();
  }
}

http://www.kler.cn/a/6311.html

相关文章:

  • 振动分析-47-振动信号处理能力提升需要理解和掌握的算法知识体系
  • 学习threejs,THREE.RingGeometry 二维平面圆环几何体
  • R语言的下载、安装及环境配置(RstudioVSCode)
  • vue中proxy代理配置(测试一)
  • 24 go语言(golang) - gorm框架安装及使用案例详解
  • WPS工具栏灰色怎么办
  • 分享一个国内可用的免费ChatGPT网站
  • 15_I.MX6ULL_LCD显示原理
  • [C++]类与对象上篇
  • DFSBFS总结
  • 《高等工程数学》习题卷(一)
  • 蓝桥杯训练day5
  • 【深度学习】基于Hough变化的答题卡识别(Matlab代码实现)
  • Text to image论文精读GigaGAN: 生成对抗网络仍然是文本生成图像的可行选择
  • day30 ● 332.重新安排行程 ● 51. N皇后 ● 37. 解数独
  • OBProxy 路由策略与使用运维-使用和运维
  • c++全排列 next_permutation()函数
  • 字节测试总监,让我们用这份《测试用例规范》,再也没加班过
  • 【故障诊断】基于最小熵反卷积、最大相关峰度反卷积和最大二阶环平稳盲反卷积等盲反卷积方法在机械故障诊断中的应用研究(Matlab代码实现)
  • vue尚品汇商城项目-day03【20.获取Banner轮播图的数据+21.使用swiper轮播图插件】
  • 【ZGC】为什么初始标记需要STW(stop the world) ?
  • 操作系统-AOSOA
  • AnaXNet: Anatomy Aware Multi-label Finding Classification in Chest X-ray
  • java14 使用增强的模式匹配切换表达式
  • Android 热修复小结
  • 从零开始实现一个C++高性能服务器框架----IO协程调度模块