ART运行时CompactingGC为新创建对象分配内存的过程分析在引进CompactingGC后,ART运行时优化了堆内存分配过程。最显著特点是为每个ART运行时线程增加局部分配缓冲区(TheadLocalAllocationBuffer)和在OOM前进行一次同构空间压缩(HomogeneousSpaceCompact)。前者可提高堆内存分配效率,后者可解决内存碎片问题。本文就对ART运行时引进CompactingGC后的堆内存分配过程进行分析。从接口层面上看,除了提供常规的对象分配接口AllocObject,ART运行时的堆还提供了一个专门用于分配非移动对象的接口AllocNonMovableObject,如图1所示:非移动对象指的是保存在前面一篇文章提到的Non-MovingSpace的对象,主要包括那些在类加载过程中创建的类对象(Class)、类方法对象(ArtMethod)和类成员变量对象(ArtField)等,以及那些在经历过若干次GenerationalSemi-SpaceGC之后仍然存活的对象。前者是通过AllocNonMovableObject接口分配的,而后者是在执行GenerationalSemi-SpaceGC过程移动过去的。本文主要关注通过AllocNonMovableObject接口分配的非移动对象。无论是通过AllocObject接口分配对象,还是通过AllocNonMovableObject接口分配对象,最后都统一调用了另外一个接口AllocObjectWithAllocator进行具体的分配过程,如下所示:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片classHeap{public:......//Allocatesandinitializesstorageforanobjectinstance.templatemirror::Object*AllocObject(Thread*self,mirror::Class*klass,size_tnum_bytes,constPreFenceVisitor&pre_fence_visitor)SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){returnAllocObjectWithAllocator(self,klass,num_bytes,GetCurrentAllocator(),pre_fence_visitor);}templatemirror::Object*AllocNonMovableObject(Thread*self,mirror::Class*klass,size_tnum_bytes,constPreFenceVisitor&pre_fence_visitor)SHARED_LOCKS_REQUIRED(Locks::mutator_lock_){returnAllocObjectWithAllocator(self,klass,num_bytes,GetCurrentNonMovingAllocator(),pre_fence_visitor);}templateALWAYS_INLINEmirror::Object*AllocObjectWithAllocator(Thread*self,mirror::Class*klass,size_tbyte_count,AllocatorTypeallocator,constPreFenceVisitor&pre_fence_visitor)SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);AllocatorTypeGetCurrentAllocator()const{returncurrent_allocator_;}AllocatorTypeGetCurrentNonMovingAllocator()const{returncurrent_non_moving_allocator_;}......private:......//Allocatortype.AllocatorTypecurrent_allocator_;constAllocatorTypecurrent_non_moving_allocator_;......};这五个函数定义在文件art/runtime/gc/heap.h在Heap类的成员函数AllocObject和AllocNonMovableObject中,参数self描述的是当前线程,klass描述的是要分配的对象所属的类型,参数num_bytes描述的是要分配的对象的大小,最后一个参数pre_fence_visitor是一个回调函数,用来在分配对象完成后在当前执行路径中执行初始化操作,例如分配完成一个数组对象,通过该回调函数立即设置数组的大小,这样就可以保证数组对象的完整性和一致性,避免多线程环境下通过加锁来完成相同的操作。Heap类的成员函数AllocObjectWithAllocator需要另外一个额外的类型为AllocatorType的参数来描述分配器的类型,也就是描述要在哪个空间分配对象。AllocatorType是一个枚举类型,它的定义如下所示:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片//Differenttypesofallocators.enumAllocatorType{kAllocatorTypeBumpPointer,//UseBumpPointerallocator,hasentrypoints.kAllocatorTypeTLAB,//UseTLABallocator,hasentrypoints.kAllocatorTypeRosAlloc,//UseRosAllocallocator,hasentrypoints.kAllocatorTypeDlMalloc,//Usedlmalloc...