ART运行时Compacting GC为新创建对象分配内存的过程分析

合集下载

jvm内存分配机制

jvm内存分配机制

JVM内存分配机制及类加载过程概述JVM(Java虚拟机)内存分配机制分为以下三个部分:
1.静态存储区(方法区):这部分内存内存在程序编译时就已经分配好,并
且在整个程序运行期间都一直存在。

主要存放静态数据,如全局static数据和常量。

2.栈区:栈内存主要存储函数(方法)中定义的基本类型变量和对象的引用
变量。

当方法执行时,方法内的局部变量都在栈内存中创建,并在方法执行结束后自动释放。

此外,JVM中的栈内存是连续的内存区域,其大小由系统决定。

3.堆区:堆区用于动态内存分配,例如通过new来申请任意大小的内存(对
象或数组)。

堆区不连续,并且需要程序员手动释放。

其内存管理依赖于垃圾回收机制。

此外,JVM在遇到new指令时,会检查该指令的参数是否能在常量池中找到一个类的符号引用,并检查这个符号引用指向的类是否被加载、解析和初始化过。

如果未完成这些步骤,则会执行类加载过程。

在类加载完成后,JVM会为新生的对象分配内存,并初始化这些内存区域。

以上信息仅供参考,如需更多信息,建议咨询专业技术人员或查阅相关书籍文献。

ART运行时ForegroundGC和BackgroundGC切换过程分析资料

ART运行时ForegroundGC和BackgroundGC切换过程分析资料

ART运行时Foreground GC和Background GC切换过程分析通过前面一系列文章的学习,我们知道了ART运行时既支持Mark-Sweep GC,又支持Compacting GC。

其中,Mark-Sweep GC执行效率更高,但是存在内存碎片问题;而Compacting GC执行效率较低,但是不存在内存碎片问题。

ART运行时通过引入Foreground GC和Background GC的概念来对这两种GC进行扬长避短。

本文就详细分析它们的执行过程以及切换过程。

在前面和这两篇文章中,我们都有提到了ART运行时的Foreground GC和Background GC。

它们是在ART运行时启动通过-Xgc和-XX:BackgroundGC指定的。

但是在某同一段时间,ART运行时只会执行Foreground GC或者Background GC。

也就是说,Foreground GC和Background GC在整个应用程序的生命周期中是交替执行的。

这就涉及到从Foreground GC 切换到Background GC,或者从Background GC切换到Foreground GC的问题。

现在两个问题就来了:什么时候执行Foreground GC,什么时候执行Background GC?什么GC作为Foreground GC最合适,什么GC作为Background GC最合适?顾名思义,Foreground指的就是应用程序在前台运行时,而Background就是应用程序在后台运行时。

因此,Foreground GC就是应用程序在前台运行时执行的GC,而Background 就是应用程序在后台运行时执行的GC。

应用程序在前台运行时,响应性是最重要的,因此也要求执行的GC是高效的。

相反,应用程序在后台运行时,响应性不是最重要的,这时候就适合用来解决堆的内存碎片问题。

因此,Mark-Sweep GC适合作为Foreground GC,而Compacting GC适合作为Background GC。

art gc流程

art gc流程

art gc流程
ART(Android Runtime)是Android平台上的Java虚拟机,它负责运行Java应用程序。

在ART运行时,垃圾回收(Garbage Collection,GC)是一个重要的机制,用于自动管理内存,避免内存泄漏和OutOfMemoryError等问题。

ART的垃圾回收流程可以分为以下几个步骤:
1.标记阶段:在这个阶段,垃圾回收器会遍历所有对象,找出并标记活动的对象。

这个过程通常被称为“标记-清除”算法的一部分。

2.清除阶段:在标记阶段完成后,垃圾回收器会清除所有未被标记的对象。

这意味着这些对象不再被应用程序使用,可以被回收并重新利用。

3.压缩阶段:在清除阶段后,垃圾回收器会对堆内存进行压缩,将所有活动的对象移动到堆内存的一端,以便于更高效地管理内存。

需要注意的是,ART的垃圾回收机制可以自动进行,也可以手动触发。

在应用程序运行过程中,ART会根据内存使用情况自动进行垃圾回收。

同时,应用程序也可以通过System.gc()方法手动触发垃圾回收,但这种方式并不建议频繁使用,因为手动触发垃圾回收可能会影响应用程序的性能。

总之,ART的垃圾回收机制是自动管理内存的重要手段,可以帮助应用程序避免内存泄漏和OutOfMemoryError等问题。

浅谈Unity中的GC以及优化

浅谈Unity中的GC以及优化

浅谈Unity中的GC以及优化介绍: 在游戏运⾏的时候,数据主要存储在内存中,当游戏的数据不在需要的时候,存储当前数据的内存就可以被回收再次使⽤。

内存垃圾是指当前废弃数据所占⽤的内存,垃圾回收(GC)是指将废弃的内存重新回收再次使⽤的过程。

Unity中将垃圾回收当作内存管理的⼀部分,如果游戏中垃圾回收⼗分复杂,则游戏的性能会受到极⼤影响,此时垃圾回收会成为游戏性能的⼀⼤障碍点。

本⽂我们主要学习垃圾回收的机制,垃圾回收如何被触发以及如何提⾼垃圾回收效率来减⼩其对游戏⾏性能的影响。

Unity内存管理机制简介 要想了解垃圾回收如何⼯作以及何时被触发,我们⾸先需要了解unity的内存管理机制。

Unity主要采⽤⾃动内存管理的机制,开发时在代码中不需要详细地告诉unity如何进⾏内存管理,unity内部⾃⾝会进⾏内存管理。

unity的⾃动内存管理可以理解为以下⼏个部分: 1)unity内部有两个内存管理池:堆内存和堆栈内存。

堆栈内存(stack)主要⽤来存储较⼩的和短暂的数据⽚段,堆内存(heap)主要⽤来存储较⼤的和存储时间较长的数据⽚段。

2)unity中的变量只会在堆栈或者堆内存上进⾏内存分配。

3)只要变量处于激活状态,则其占⽤的内存会被标记为使⽤状态,则该部分的内存处于被分配的状态,变量要么存储在堆栈内存上,要么处于堆内存上。

4)⼀旦变量不再激活,则其所占⽤的内存不再需要,该部分内存可以被回收到内存池中被再次使⽤,这样的操作就是内存回收。

处于堆栈上的内存回收及其快速,处于堆上的内存并不是及时回收的,其对应的内存依然会被标记为使⽤状态。

5) 垃圾回收主要是指堆上的内存分配和回收,unity中会定时对堆内存进⾏GC操作。

在了解了GC的过程后,下⾯详细了解堆内存和堆栈内存的分配和回收机制的差别。

堆栈内存分配和回收机制 堆栈上的内存分配和回收⼗分快捷简单,主要是堆栈上只会存储短暂的较⼩的变量。

JVM的内存管理机制详解

JVM的内存管理机制详解

JVM的内存管理机制详解JVM(Java Virtual Machine)是Java编程语言的基础,它允许Java应用程序在不同的操作系统上运行。

JVM负责将Java字节码翻译成机器可执行的指令,并管理Java应用程序的内存。

JVM的内存管理机制包括垃圾回收、内存分配和内存优化等方面。

下面将详细介绍JVM的内存管理机制。

1. 堆内存(Heap Memory):堆内存是JVM中最大的一块内存区域,用于存储对象实例。

我们创建的所有对象都存放在这个区域中。

堆内存由新生代和老年代组成。

新生代又分为Eden区和两个Survivor区,用于存放新创建的对象,而老年代存放存活时间较长的对象。

2. 栈内存(Stack Memory):栈内存用于存储Java方法的局部变量、方法参数和临时变量。

每个线程在执行方法的时候都会创建一个栈帧,栈帧包含了方法的局部变量和操作数栈。

栈帧的大小在方法编译时就确定了,因此栈内存的分配和回收是非常快速和高效的。

3. 方法区(Method Area):方法区用于存储已加载的类信息、常量、静态变量和编译后的代码等数据。

方法区在JVM启动时被创建,并且在JVM关闭时销毁。

方法区中存放的数据是共享的,所有线程共享同一块方法区内存。

4. 本地方法栈(Native Method Stack):本地方法栈用于存储Java应用程序调用本地方法的相关信息。

本地方法栈和栈内存的作用类似,不同之处在于本地方法栈存储的是本地方法调用相关的数据。

5. PC寄存器(Program Counter Register):PC寄存器用于存储当前线程执行的字节码指令地址。

每个线程都有独立的PC寄存器,用于控制线程的执行。

6. 垃圾回收(Garbage Collection):垃圾回收是JVM的一个重要特性,用于自动回收不再使用的对象和释放内存空间。

JVM中的垃圾回收器会定期扫描堆内存,将不再使用的对象标记为垃圾,并进行回收。

jvm 对象分配过程

jvm 对象分配过程

JVM对象分配过程1. 概述JVM(Java虚拟机)是Java程序运行的环境,它负责解释和执行Java字节码。

在Java程序中,对象是一种重要的数据结构,而JVM对于对象的分配和管理是非常关键的。

本文将深入探讨JVM对象分配的过程,包括对象的创建、内存分配、初始化和回收等。

2. 对象创建在Java程序中,通过new关键字来创建一个对象。

当执行new操作时,JVM会进行如下步骤: - 检查类是否已经加载到内存中,如果没有则进行类加载; - 在堆内存中为对象分配一块连续的内存空间; - 执行对象的构造方法进行初始化; - 返回对象引用。

3. 内存分配在JVM中,所有的对象都被分配在堆(Heap)上。

堆是一块动态分配的内存区域,用于存储所有的Java对象。

当执行new操作时,JVM会自动在堆上为对象分配内存空间。

3.1 对象头每个在堆上分配的对象都有一个与之对应的对象头(Object Header)。

对象头包含了一些必要信息,如: - 对象类型指针:用于确定该对象属于哪个类; - GC 标记位:用于标记对象是否可回收; - 锁标志位:用于实现同步机制。

3.2 内存分配方式JVM采用两种方式来进行内存分配:指针碰撞(Bump the Pointer)和空闲列表(Free List)。

3.2.1 指针碰撞指针碰撞是一种简单且高效的内存分配方式。

当堆中的空闲内存与已使用的内存之间有一块完全空闲的区域时,JVM可以通过移动一个指针来分配内存。

这个指针称为“指针碰撞指针”,它将堆分为两个部分:已使用的部分和未使用的部分。

3.2.2 空闲列表空闲列表是另一种常见的内存分配方式。

在这种方式下,JVM会维护一个链表,记录所有空闲的内存块。

当需要为对象分配内存时,JVM会遍历链表,找到合适大小的内存块,并将其从链表中移除。

4. 对象初始化在对象创建完成后,JVM会调用对象的构造方法进行初始化。

构造方法负责对对象进行初始化操作,如成员变量赋初值、执行其他初始化方法等。

ART运行时Semi-Space(SS)和Generational Semi-Space(GSS)GC执行过程分析

ART运行时Semi-Space(SS)和Generational Semi-Space(GSS)GC执行过程分析Semi-Space(SS)GC和Generational Semi-Space(GSS)GC是ART运行时引进的两个Compacting GC。

它们的共同特点是都具有一个From Space和一个To Space。

在GC执行期间,在From Space分配的还存活的对象会被依次拷贝到To Space中,这样就可以达到消除内存碎片的目的。

本文就将SS GC和GSS GC的执行过程分析进行详细分析。

与SS GC相比,GSS GC还多了一个Promote Space。

当一个对象是在上一次GC之前分配的,并且在当前GC中仍然是存活的,那么它就会被拷贝到Promote Space中,而不是To Space 中。

这相当于是简单地将对象划分为新生代和老生代的,即在上一次GC之前分配的对象属于老生代的,而在上一次GC之后分配的对象属于新生代的。

一般来说,老生代对象的存活性要比新生代的久,因此将它们拷贝到Promote Space中去,可以避免每次执行SS GC或者GSS GC时,都需要对它们进行无用的处理。

总结来说,SS GC和GSS GC的执行过程就如图1和图2所示:在图1和图2中,Bump Pointer Space 1和Bump Pointer Space 2就是我们前面说的From Space 和To Space。

接下来我们就结合源码来详细分析它们的执行过程。

从前面一文可以知道,在ART运行时内部,都是通过调用Heap类的成员函数CollectGarbageInternal开始执行GC的,因此,我们就从它开始分析SS GC和GSS GC的执行过程。

Heap类的成员函数CollectGarbageInternal的实现如下所示:[cpp] view plain copycollector::GcType Heap::CollectGarbageInternal(collector::GcType gc_type, GcCause gc_cause,bool clear_soft_references) {Thread* self = Thread::Current();Runtime* runtime = Runtime::Current();......bool compacting_gc;{......MutexLock mu(self, *gc_complete_lock_);// Ensure there is only one GC at a time.WaitForGcToCompleteLocked(gc_cause, self);compacting_gc = IsMovingGc(collector_type_);// GC can be disabled if someone has a used GetPrimitiveArrayCritical.if (compacting_gc && disable_moving_gc_count_ != 0) {......return collector::kGcTypeNone;}collector_type_running_ = collector_type_;}......collector::GarbageCollector* collector = nullptr;// TODO: Clean this up.if (compacting_gc) {......switch (collector_type_) {case kCollectorTypeSS:// Fall-through.case kCollectorTypeGSS:semi_space_collector_->SetFromSpace(bump_pointer_space_);semi_space_collector_->SetToSpace(temp_space_);semi_space_collector_->SetSwapSemiSpaces(true);collector = semi_space_collector_;break;case kCollectorTypeCC:collector = concurrent_copying_collector_;break;case kCollectorTypeMC:mark_compact_collector_->SetSpace(bump_pointer_space_);collector = mark_compact_collector_;break;default:LOG(FATAL) << "Invalid collector type " << static_cast<size_t>(collector_type_);}......gc_type = collector::kGcTypeFull; // TODO: Not hard code this in.}......collector->Run(gc_cause, clear_soft_references || runtime->IsZygote());......RequestHeapTrim();// Enqueue cleared references.reference_processor_.EnqueueClearedReferences(self);// Grow the heap so that we know when to perform the next GC.GrowForUtilization(collector);......FinishGC(self, gc_type);......return gc_type;}这个函数定义在文件art/runtime/gc/中。

对象内存空间分配安排

对象内存空间分配安排
对象在内存中的分配有两种方式:
1. 静态分配:对象分配在栈上。

在编译期间确定对象存储空间大小,将对象直接分配在栈上。

当执行到对象的作用域结束时,对象的内存空间会自动释放。

这种方式的优点是分配和释放内存非常快,缺点是对象的大小必须在编译期间确定,不适用于动态分配内存的场景。

2. 动态分配:对象分配在堆上。

在运行时根据需要动态分配对象的内存空间。

通过 new、malloc 或者其他动态分配内存的方式在堆上分配对象内存空间。

分配的对象内存空间需要手动释放,否则会造成内存泄漏。

需要注意的是,C++中的对象分配和释放一般是由编译器自动
完成的,通过构造函数和析构函数来自动调用。

例如,当定义一个对象时,编译器会在栈上分配对象内存,并调用对象的构造函数进行初始化;当对象作用域结束时,编译器会自动调用对象的析构函数释放内存。

如果需要手动分配和释放内存,可以使用 new 和 delete 关键字。

art运行时垃圾收集(gc)过程分析.doc

ART运行时垃圾收集(GC)过程分析ART运行时与Dalvik虚拟机一样,都使用了Mark-Sweep算法进行垃圾回收,因此它们的垃圾回收流程在总体上是一致的。

但是ART运行时对堆的划分更加细致,因而在此基础上实现了更多样的回收策略。

不同的策略有不同的回收力度,力度越大的回收策略,每次回收的内存就越多,并且它们都有各自的使用情景。

这样就可以使得每次执行GC时,可以最大限度地减少应用程序停顿。

本文就详细分析ART运行时的垃圾收集过程。

ART运行时的垃圾收集收集过程如图1所示:图1的最上面三个箭头描述触发GC的三种情况,左边的流程图描述非并行GC的执行过程,右边的流程图描述并行GC的执行流程,接下来我们就详细图中涉及到的所有细节。

在前面一文中,我们提到了两种可能会触发GC的情况。

第一种情况是没有足够内存分配请求的分存时,会调用Heap类的成员函数CollectGarbageInternal触发一个原因为kGcCauseForAlloc的GC。

第二种情况下分配出请求的内存之后,堆剩下的内存超过一定的阀值,就会调用Heap类的成员函数RequestConcurrentGC请求执行一个并行GC。

Heap类的成员函数RequestConcurrentGC的实现如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片void Heap::RequestConcurrentGC(Thread* self) {// Make sure that we can do a concurrent GC.Runtime* runtime = Runtime::Current();DCHECK(concurrent_gc_);if (runtime == NULL || !runtime->IsFinishedStarting() ||!runtime->IsConcurrentGcEnabled()) {return;}{MutexLock mu(self, *Locks::runtime_shutdown_lock_);if (runtime->IsShuttingDown()) {return;}}if (self->IsHandlingStackOverflow()) {return;}// We already have a request pending, no reason to start more until we update// concurrent_start_bytes_.concurrent_start_bytes_ = std::numeric_limits<size_t>::max();JNIEnv* env = self->GetJniEnv();DCHECK(WellKnownClasses::java_lang_Daemons != NULL);DCHECK(WellKnownClasses::java_lang_Daemons_requestGC != NULL);env->CallStaticV oidMethod(WellKnownClasses::java_lang_Daemons,WellKnownClasses::java_lang_Daemons_requestGC); CHECK(!env->ExceptionCheck());}这个函数定义在文件art/runtime/gc/。

gc的工作原理

gc的工作原理
GC(垃圾回收)是一种自动管理内存的机制,主要用于回收不再使用的内存空间,以便继续为程序分配内存。

GC的工作原理如下:
1. 标记阶段(Marking):从根对象开始,通过遍历对象图的方式,标记所有与根对象直接或间接相关的对象。

被标记的对象会被视为存活对象。

2. 清除阶段(Sweeping):遍历整个堆,将没有被标记的对象进行清除,并释放其所占用的内存空间。

3. 压缩阶段(Compacting):将存活的对象压缩到一侧,使内存空间连续,以便之后分配内存空间。

GC的工作原理是基于可达性分析的,即通过判断对象是否与根对象相连来确定对象是否存活。

根对象包括:活动线程的栈中的本地变量、静态字段和静态方法,以及JNI(Java Native Interface)引用和虚拟机内部的一些特殊对象。

GC的主要优势是自动管理内存,大大减轻了程序员手动回收内存的负担。

然而,它也会引入一定的性能开销,因为GC需要消耗一定的计算资源和时间来执行垃圾回收操作。

因此,在设计和开发应用程序时,需要合理使用和管理对象,以最大程度地减少垃圾回收的频率和代价。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

ART运行时Compacting GC为新创建对象分配内存的过程分析在引进Compacting GC后,ART运行时优化了堆内存分配过程。

最显著特点是为每个ART 运行时线程增加局部分配缓冲区(Thead Local Allocation Buffer)和在OOM前进行一次同构空间压缩(Homogeneous Space Compact)。

前者可提高堆内存分配效率,后者可解决内存碎片问题。

本文就对ART运行时引进Compacting GC后的堆内存分配过程进行分析。

从接口层面上看,除了提供常规的对象分配接口AllocObject,ART运行时的堆还提供了一个专门用于分配非移动对象的接口AllocNonMovableObject,如图1所示:非移动对象指的是保存在前面一篇文章提到的Non-Moving Space的对象,主要包括那些在类加载过程中创建的类对象(Class)、类方法对象(ArtMethod)和类成员变量对象(ArtField)等,以及那些在经历过若干次Generational Semi-Space GC之后仍然存活的对象。

前者是通过AllocNonMovableObject接口分配的,而后者是在执行Generational Semi-Space GC过程移动过去的。

本文主要关注通过AllocNonMovableObject接口分配的非移动对象。

无论是通过AllocObject接口分配对象,还是通过AllocNonMovableObject接口分配对象,最后都统一调用了另外一个接口AllocObjectWithAllocator进行具体的分配过程,如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片class Heap {public:......// Allocates and initializes storage for an object instance.template <bool kInstrumented, typename PreFenceVisitor>mirror::Object* AllocObject(Thread* self, mirror::Class* klass, size_t num_bytes,const PreFenceVisitor& pre_fence_visitor)SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {return AllocObjectWithAllocator<kInstrumented, true>(self, klass, num_bytes,GetCurrentAllocator(),pre_fence_visitor);}template <bool kInstrumented, typename PreFenceVisitor>mirror::Object* AllocNonMovableObject(Thread* self, mirror::Class* klass, size_t num_bytes,const PreFenceVisitor& pre_fence_visitor) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {return AllocObjectWithAllocator<kInstrumented, true>(self, klass, num_bytes,GetCurrentNonMovingAllocator(),pre_fence_visitor);}template <bool kInstrumented, bool kCheckLargeObject, typename PreFenceVisitor> ALWAYS_INLINE mirror::Object* AllocObjectWithAllocator(Thread* self, mirror::Class* klass, size_t byte_count, AllocatorType allocator,const PreFenceVisitor& pre_fence_visitor)SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);AllocatorType GetCurrentAllocator() const {return current_allocator_;}AllocatorType GetCurrentNonMovingAllocator() const {return current_non_moving_allocator_;}......private:......// Allocator type.AllocatorType current_allocator_;const AllocatorType current_non_moving_allocator_;......};这五个函数定义在文件art/runtime/gc/heap.h在Heap类的成员函数AllocObject和AllocNonMovableObject中,参数self描述的是当前线程,klass描述的是要分配的对象所属的类型,参数num_bytes描述的是要分配的对象的大小,最后一个参数pre_fence_visitor是一个回调函数,用来在分配对象完成后在当前执行路径中执行初始化操作,例如分配完成一个数组对象,通过该回调函数立即设置数组的大小,这样就可以保证数组对象的完整性和一致性,避免多线程环境下通过加锁来完成相同的操作。

Heap类的成员函数AllocObjectWithAllocator需要另外一个额外的类型为AllocatorType的参数来描述分配器的类型,也就是描述要在哪个空间分配对象。

AllocatorType是一个枚举类型,它的定义如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片// 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.};这个枚举类型定义在文件/art/runtime/gc/allocator_type.h。

AllocatorType一共有六个值,它们的含义如下所示:kAllocatorTypeBumpPointer:表示在Bump Pointer Space中分配对象。

kAllocatorTypeTLAB:表示要在由Bump Pointer Space提供的线程局部分配缓冲区中分配对象。

kAllocatorTypeRosAlloc:表示要在Ros Alloc Space分配对象。

kAllocatorTypeDlMalloc:表示要在Dl Malloc Space分配对象。

kAllocatorTypeNonMoving:表示要在Non Moving Space分配对象。

kAllocatorTypeLOS:表示要在Large Object Space分配对象。

Heap类的成员函数AllocObject和AllocNonMovableObject使用的分配器类型分别是由成员变量current_allocator_和current_non_moving_allocator_决定的。

前者的值与当前使用的GC类型有关。

当GC类型发生变化时,就会调用Heap类的成员函数ChangeCollector来修改当前使用的GC,同时也会调用另外一个成员函数ChangeAllocator来修改Heap类的成员变量current_allocator_的值。

由于ART运行时只有一个Non-Moving Space,因此后者的值就固定为kAllocatorTypeNonMoving。

Heap类的成员函数ChangeCollector的实现如下所示:[cpp] view plain copy 在CODE上查看代码片派生到我的代码片void Heap::ChangeCollector(CollectorType collector_type) {// TODO: Only do this with all mutators suspended to avoid races.if (collector_type != collector_type_) {......collector_type_ = collector_type;gc_plan_.clear();switch (collector_type_) {case kCollectorTypeCC: // Fall-through.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: {LOG(FATAL) << "Unimplemented";}}......}}这个函数定义在文件ime/gc/中。

相关文档
最新文档