GC目前只有四种基本方法:
(1)Mark-Sweep Collection 标记清除算法
(2)Copying Collection 复制算法
(3)Mark-Compact Collection 标记-压缩算法
(3)Reference Counting 引用计数算法--未被art采用
目前art默认使用的GC方案:
concurrent copying(CC) 并发复制算法
(1)吞吐量 throughput 管理的堆大小/GC总时长
(2)最大暂停时间 pause time 垃圾回收器运行时,应用程序的最大暂停时间
(3)堆(空间)使用效率 space overhead,决定堆使用效率因素:(1)头大小 (2)堆用法
对象是GC的基本单位,对象由头(header)和域(field)构成
头:对象的大小,对象的种类
域:指针和非指针两种
(4)访问的局部性
其他指标
(5)垃圾回收器负载
(6)垃圾回收频率 垃圾回收器多长时间运行一次。一般而言,频率越低越好,通常增大堆空间可以有效降低垃圾回收发生的频率,但是会增加回收时产生的停顿时间。
(7)反应时间 当一个对象成为垃圾后,多长时间内,它所占用的内存空间会被释放掉。
(1)编译配置设置默认回收器:
在/art/build/art.go
39 gcType := envDefault(ctx, "ART_DEFAULT_GC_TYPE", "CMS")
40
41 if envTrue(ctx, "ART_TEST_DEBUG_GC") {
42 gcType = "SS"
43 tlab = true
44 }
45
46 cflags = append(cflags, "-DART_DEFAULT_GC_TYPE_IS_"+gcType)
47 if tlab {
48 cflags = append(cflags, "-DART_USE_TLAB=1")
49 }
默认回收器只支持CMS, SS, GSS, CC 四种,默认CMS
但是在heap创建的时候如果支持kUseReadBarrier,则会前台默认使用CC, 后台使用CCBackground ,目前是支持这个的,所以我们现在art用的是CC方案。
kUseReadBarrier ? gc::kCollectorTypeCC : xgc_option.collector_type_,
kUseReadBarrier ? BackgroundGcOption(gc::kCollectorTypeCCBackground)
: runtime_options.GetOrDefault(Opt::BackgroundGc),
static constexpr bool kUseReadBarrier =
kUseBakerReadBarrier || kUseBrooksReadBarrier || kUseTableLookupReadBarrier;
|
|
USE_BAKER_READ_BARRIER |
kUseBakerReadBarrier = true |
---|---|---|---|
|
USE_BROOKS_READ_BARRIER |
kUseBrooksReadBarrier=true | |
|
USE_TABLE_LOOKUP_READ_BARRIER |
kUseTableLookupReadBarrier=true |
(3)通过属性设置回收器
前台回收器设置方法:
GC类型设置,前提要把kUseReadBarrier的判断去掉由runtime传入的参数决定,更改前台 GC 计划的主要方法是更改 dalvik.vm.gctype 属性或传递 -Xgc: 选项
参数 -Xgc:
属性值 dalvik.vm.gctype
后台回收器设置方法:
参数 -XX:BackgroundGC=
属性值 dalvik.vm.backgroundgctype
后台回收器的决定逻辑如下
art/runtime/parsed_options.cc
613 background_collector_type_ = args.GetOrDefault(M::BackgroundGc);
614 {
615 XGcOption* xgc = args.Get(M::GcOption);
616 if (xgc != nullptr && xgc->collector_type_ != gc::kCollectorTypeNone) {
617 collector_type_ = xgc->collector_type_;
618 }
619 }
620
621 if (background_collector_type_ == gc::kCollectorTypeNone) {
622 if (collector_type_ != gc::kCollectorTypeGSS) {
623 background_collector_type_ = low_memory_mode_ ?
624 gc::kCollectorTypeSS : gc::kCollectorTypeHomogeneousSpaceCompact;
625 } else {
626 background_collector_type_ = collector_type_;
627 }
628 }
1.前台 GSS,后台也是GSS
2.前台非GSS,低内存模式,后台为SS,非低内存模式后台为HSC
Collector Type |
option |
Comment (English) |
comment |
---|---|---|---|
kCollectorTypeMS | MS | Non concurrent mark-sweep | 非并发标记-清除 |
kCollectorTypeCMS | CMS | CMS Concurrent mark-sweep. | 并发标记-清除 |
kCollectorTypeSS | SS | Semi-space / mark-sweep hybrid, enables compaction. | 半空间压缩 |
kCollectorTypeGSS | GSS | A generational variant of kCollectorTypeSS | 分代的半空间压缩 |
|
|
Mark compact collector | 标记-压缩 |
kCollectorTypeHeapTrim | Heap trimming collector, doesn't do any actual collecting. | 主要是使用TrimSpace函数进行消减空间对象空闲内存资源的时候传入的回收器类型,一般是heap trim触发的。 | |
kCollectorTypeCC | CC | A (mostly) concurrent copying collector. | 并发复制回收 |
kCollectorTypeCCBackground | CCBackground | The background compaction of the concurrent copying collector. | 后台并发复制回收 |
kCollectorTypeInstrumentation | Instrumentation critical section fake collector. | ||
kCollectorTypeAddRemoveAppImageSpace | Fake collector for adding or removing application image spaces. | ||
kCollectorTypeDebugger | Fake collector used to implement exclusion between GC and debugger. | ||
kCollectorTypeHomogeneousSpaceCompact | A homogeneous space compaction collector used in background transition when both foreground and background collector are CMS. | 同构空间压缩(HSC),用于后台回收器类型 | |
kCollectorTypeClassLinker | Class linker fake collector. | ||
kCollectorTypeJitCodeCache | JIT Code cache fake collector. | ||
kCollectorTypeHprof | Hprof fake collector. | ||
kCollectorTypeAddRemoveSystemWeakHolder | Fake collector for installing/removing a system-weak holder. | ||
kCollectorTypeGetObjectsAllocated | Fake collector type for GetObjectsAllocated | ||
kCollectorTypeCriticalSection | Fake collector type for ScopedGCCriticalSection |
主要决定回收力度
GcType |
comment |
---|---|
GcType |
comment |
kGcTypeSticky | 只回收上次GC后在Allocation Space中新分配的垃圾对象 |
kGcTypePartial | 只回收Allocation Space的垃圾对象 |
kGcTypeFull | 同时回收Zygote Space和Allocation Space的垃圾对象 |
kGcTypeMax |
垃圾回收类型的不同也决定了heap内存区域有不同的划分。heap的内存管理是通过Space划分的,不同的Space功能是有区别的。
这里主要解释CC 回收器初始化的heap space 类型
ImageSpace 主要用来管理加载到内存中的art文件
Zygote Space Zygote进程的heap区
LargeObjeactSpace 主要管理存放大对象的内存区域
RegionSpace 常规内存对象的分配区域
Allocator Type |
内存分配器 |
分配策略 |
对象所在的堆空间 |
---|---|---|---|
|
RosAlloc | 分箱式分配 | Main space |
|
TLAB | 线程私有分配区 | Bump Pointer Space |
|
BumpPointer | 头尾相连分配 | Bump Pointer Space |
|
DlMalloc | 分箱式分配 | Main space |
|
NonMoving | 不移动对象分配策略 | Non-Moving Space |
|
LOS | 专门分配大对象 | Large Object Space |
|
|
分域管理,顺序分配 | |
|
|
线程私有的Region分配 | |
一.分配器和回收器的设置
desired_collector_type_(foreground_collector_type_),
ChangeCollector(desired_collector_type_);
Heap::ChangeCollector()
(1)collector_type_ 全局变量,当前的回收器类型,默认none
(2)gc_plan_ 存放回收策略 ,也就是GcType,主要回收力度的区别
Collector Type |
gc_plan_ |
---|---|
CC | use_generational_cc_?kGcTypeSticky kGcTypeFull |
SS/GSS | kGcTypeFull |
MS | kGcTypeSticky kGcTypePartial kGcTypeFull |
CMS | kGcTypeSticky kGcTypePartial kGcTypeFull |
(3)ChangeAllocator 设置内存分配器
Collector Type |
Allocator Type(use_tlab_) |
Allocator Type |
---|---|---|
CC | kAllocatorTypeRegionTLAB | kAllocatorTypeRegion |
SS/GSS |
kAllocatorTypeTLAB | kAllocatorTypeBumpPointer |
Collector Type |
Allocator Type(kUseRosAlloc) |
Allocator Type |
---|---|---|
MS | kAllocatorTypeRosAlloc | kAllocatorTypeDlMalloc |
CMS |
kAllocatorTypeRosAlloc | kAllocatorTypeDlMalloc |
二.根据回收类型决定回收器子类的实例
heap 初始化的时候根据配置的前后台回收器类型 foreground_collector_type_ 和 background_collector_type_ 来决定实例不同的回收器子类,
并将对应的实例存放入garbage_collectors_
std::vector
(1)使用CMS和MS的回收器,需要实例化MarkSweep,PartialMarkSweep,StickyMarkSweep 这三个回收器,区别在于入参的concurrent 是否为true,是否是并发的。
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));
}
}
(2)使用SS,GSS,HSC 这三种压缩回收器,一般都是后台回收器,需要实例化SemiSpace ,其中generational 参数代表是否是分代的。
if (MayUseCollector(kCollectorTypeSS) || MayUseCollector(kCollectorTypeGSS) ||
MayUseCollector(kCollectorTypeHomogeneousSpaceCompact) ||
use_homogeneous_space_compaction_for_oom_) {
// TODO: Clean this up.
const bool generational = foreground_collector_type_ == kCollectorTypeGSS;
semi_space_collector_ = new collector::SemiSpace(this, generational,
generational ? "generational" : "");
garbage_collectors_.push_back(semi_space_collector_);
}
(3)使用CC 回收器,创建ConcurrentCopying实例,如果use_generational_cc_ 为true,多创建一个ConcurrentCopying实例,这个实例入参有区别,这个参数主要是是否分代的。
if (MayUseCollector(kCollectorTypeCC)) {
concurrent_copying_collector_ = new collector::ConcurrentCopying(this,
/*young_gen=*/false,
use_generational_cc_,
"",
measure_gc_performance);
if (use_generational_cc_) {
young_concurrent_copying_collector_ = new collector::ConcurrentCopying(
this,
/*young_gen=*/true,
use_generational_cc_,
"young",
measure_gc_performance);
}
active_concurrent_copying_collector_ = concurrent_copying_collector_;
DCHECK(region_space_ != nullptr);
concurrent_copying_collector_->SetRegionSpace(region_space_);
if (use_generational_cc_) {
young_concurrent_copying_collector_->SetRegionSpace(region_space_);
// At this point, non-moving space should be created.
DCHECK(non_moving_space_ != nullptr);
concurrent_copying_collector_->CreateInterRegionRefBitmaps();
}
garbage_collectors_.push_back(concurrent_copying_collector_);
if (use_generational_cc_) {
garbage_collectors_.push_back(young_concurrent_copying_collector_);
}
}
GC执行
GarbageCollector 类是所有回收器类型的基类
GC的执行是从GarbageCollector::Run 开始,具体由子类RunPhases函数执行