freepeople性欧美熟妇, 色戒完整版无删减158分钟hd, 无码精品国产vα在线观看DVD, 丰满少妇伦精品无码专区在线观看,艾栗栗与纹身男宾馆3p50分钟,国产AV片在线观看,黑人与美女高潮,18岁女RAPPERDISSSUBS,国产手机在机看影片

正文內(nèi)容

art運(yùn)行時(shí)compactinggc為新創(chuàng)建對(duì)象分配內(nèi)存的過(guò)程分析(編輯修改稿)

2025-07-22 06:02 本頁(yè)面
 

【文章內(nèi)容簡(jiǎn)介】 public: ...... static ALWAYS_INLINE bool AllocatorHasAllocationStack(AllocatorType allocator_type) { return allocator_type != kAllocatorTypeBumpPointer amp。amp。 allocator_type != kAllocatorTypeTLAB。 } ...... }。 這個(gè)函數(shù)定義在文件art/runtime/gc/。 前面提到,ART運(yùn)行時(shí)線程的TLAB是來(lái)自于Bump Pointer Space的,而B(niǎo)ump Pointer Space是與Compacting GC相關(guān)的,Allocation Stack是與Sticky GC相關(guān)的,這就意味著Compacting GC不會(huì)執(zhí)行Sticky類(lèi)型的GC。 第二件事情是調(diào)用Heap類(lèi)的成員函數(shù)AllocatorMayHaveConcurrentGC判斷參數(shù)allocator指定的分配器是否與Concurrent GC相關(guān),并且當(dāng)前使用的GC就是一個(gè)Concurrent GC。如果條件都成立的話,就調(diào)用Heap類(lèi)的成員函數(shù)CheckConcurrentGC檢查是否需要發(fā)起一個(gè)Concurrent GC請(qǐng)求。 Heap類(lèi)的成員函數(shù)AllocatorMayHaveConcurrentGC的實(shí)現(xiàn)如下所示:[cpp] view plain copy 在CODE上查看代碼片派生到我的代碼片class Heap { public: ...... static ALWAYS_INLINE bool AllocatorMayHaveConcurrentGC(AllocatorType allocator_type) { return AllocatorHasAllocationStack(allocator_type)。 } ...... }。 這個(gè)函數(shù)定義在文件art/runtime/gc/。 Heap類(lèi)的成員函數(shù)AllocatorMayHaveConcurrentGC的判斷邏輯與上面分析的成員函數(shù)AllocatorHasAllocationStack是一樣的,這就意味著目前提供的Compacting GC都是非Concurrent的。不過(guò)以后是會(huì)提供具有Concurrent功能的Compacting GC的,稱(chēng)為Concurrent Copying GC。 以上就是Heap類(lèi)的成員函數(shù)AllocObjectWithAllocator的實(shí)現(xiàn),接下來(lái)我們繼續(xù)分析Heap類(lèi)的成員函數(shù)TryToAllocate和AllocateInternalWithGc的實(shí)現(xiàn),以便可以更好地了解ART運(yùn)行時(shí)分配對(duì)象的過(guò)程。這也有利用我們后面分析ART運(yùn)行時(shí)的Compacting GC的執(zhí)行過(guò)程。 Heap類(lèi)的成員函數(shù)TryToAllocate的實(shí)現(xiàn)如下所示:[cpp] view plain copy 在CODE上查看代碼片派生到我的代碼片template const bool kInstrumented, const bool kGrow inline mirror::Object* Heap::TryToAllocate(Thread* self, AllocatorType allocator_type, size_t alloc_size, size_t* bytes_allocated, size_t* usable_size) { if (allocator_type != kAllocatorTypeTLAB amp。amp。 UNLIKELY(IsOutOfMemoryOnAllocationkGrow(allocator_type, alloc_size))) { return nullptr。 } mirror::Object* ret。 switch (allocator_type) { case kAllocatorTypeBumpPointer: { DCHECK(bump_pointer_space_ != nullptr)。 alloc_size = RoundUp(alloc_size, space::BumpPointerSpace::kAlignment)。 ret = bump_pointer_space_AllocNonvirtual(alloc_size)。 if (LIKELY(ret != nullptr)) { *bytes_allocated = alloc_size。 *usable_size = alloc_size。 } break。 } case kAllocatorTypeRosAlloc: { if (kInstrumented amp。amp。 UNLIKELY(running_on_valgrind_)) { // If running on valgrind, we should be using the instrumented path. ret = rosalloc_space_Alloc(self, alloc_size, bytes_allocated, usable_size)。 } else { DCHECK(!running_on_valgrind_)。 ret = rosalloc_space_AllocNonvirtual(self, alloc_size, bytes_allocated, usable_size)。 } break。 } case kAllocatorTypeDlMalloc: { if (kInstrumented amp。amp。 UNLIKELY(running_on_valgrind_)) { // If running on valgrind, we should be using the instrumented path. ret = dlmalloc_space_Alloc(self, alloc_size, bytes_allocated, usable_size)。 } else { DCHECK(!running_on_valgrind_)。 ret = dlmalloc_space_AllocNonvirtual(self, alloc_size, bytes_allocated, usable_size)。 } break。 } case kAllocatorTypeNonMoving: { ret = non_moving_space_Alloc(self, alloc_size, bytes_allocated, usable_size)。 break。 } case kAllocatorTypeLOS: { ret = large_object_space_Alloc(self, alloc_size, bytes_allocated, usable_size)。 // Note that the bump pointer spaces aren39。t necessarily next to // the other continuous spaces like the nonmoving alloc space or // the zygote space. DCHECK(ret == nullptr || large_object_space_Contains(ret))。 break。 } case kAllocatorTypeTLAB: { DCHECK_ALIGNED(alloc_size, space::BumpPointerSpace::kAlignment)。 if (UNLIKELY(selfTlabSize() alloc_size)) { const size_t new_tlab_size = alloc_size + kDefaultTLABSize。 if (UNLIKELY(IsOutOfMemoryOnAllocationkGrow(allocator_type, new_tlab_size))) { return nullptr。 } // Try allocating a new thread local buffer, if the allocaiton fails the space must be // full so return nullptr. if (!bump_pointer_space_AllocNewTlab(self, new_tlab_size)) { return nullptr。 } *bytes_allocated = new_tlab_size。 } else { *bytes_allocated = 0。 } // The allocation can39。t fail. ret = selfAllocTlab(alloc_size)。 DCHECK(ret != nullptr)。 *usable_size = alloc_size。 break。 } default: { LOG(FATAL) Invalid allocator type。 ret = nullptr。 } } return ret。 } 這個(gè)函數(shù)定義在文件art/runtime/gc/。 Heap類(lèi)的成員函數(shù)TryToAllocate的實(shí)現(xiàn)是很直覺(jué)的,我們可以通過(guò)圖3來(lái)描述:首先,如果不是指定在當(dāng)前ART運(yùn)行時(shí)線程的TLAB中分配對(duì)象,并且指定分配的對(duì)象大小超出了當(dāng)前堆的限制,那么就會(huì)分配失敗,返回一個(gè)nullptr指針。 接下來(lái),就根據(jù)參數(shù)allocator指定的分配器在不同的Space中分配對(duì)象: 1. 指定在Bump Pointer Space中分配對(duì)象,就調(diào)用Heap類(lèi)的成員變量bump_pointer_space_指向的一個(gè)BumpPointerSpace對(duì)象的成員函數(shù)AllocNonvirtual分配指定大小的內(nèi)存。 2. 指定在Ros Alloc Space中分配對(duì)象,就調(diào)用Heap類(lèi)的成員變量rosalloc_space_指向的一個(gè)RosAllocSpace對(duì)象的成員函數(shù)Alloc者AllocNonvirtual分配指定大小的內(nèi)存。當(dāng)模板參數(shù)kInstrumented的值等于true,并且Heap類(lèi)的成員變量running_on_valgrind_的值等于true時(shí),就調(diào)用RosAllocSpace類(lèi)的成員函數(shù)Alloc進(jìn)行分配。否則的話,就調(diào)用RosAllocSpace類(lèi)的成員函數(shù)AllocNonvirtual進(jìn)行分配。從Heap類(lèi)的成員變量running_on_valgrind_的命令就可以很容易推斷出,調(diào)用RosAllocSpace類(lèi)的成員函數(shù)Alloc分配的內(nèi)存具有非法內(nèi)存訪問(wèn)檢查功能,在前面一篇文章中,我們有提到這種內(nèi)存分配方式。 3. 指定在Dl Malloc Space中分配對(duì)象,就調(diào)用Heap類(lèi)的成員變量dlmalloc_space_指向的一個(gè)DlMallocSpace對(duì)象的成員函數(shù)Alloc者AllocNonvirtual分配指定大小的內(nèi)存。這一點(diǎn)與在Ros Alloc Space中分配對(duì)象的邏輯是完全一致的,除了一個(gè)是在Dl Malloc Space中分配內(nèi)存, 另一個(gè)是在Ros Alloc Space中分配對(duì)象之外。 4. 指定在Non Moving Space中分配對(duì)象,就調(diào)用Heap類(lèi)的成員變量non_moving_space_指向的一個(gè)RosAllocSpace對(duì)象或者DlMallocSpace對(duì)象的成員函數(shù)Alloc分配指定大小的內(nèi)存。從前面一文可以知道,Heap類(lèi)的成員變量non_moving_space_指向的可能是一個(gè)Ro
點(diǎn)擊復(fù)制文檔內(nèi)容
環(huán)評(píng)公示相關(guān)推薦
文庫(kù)吧 www.dybbs8.com
備案圖片鄂ICP備17016276號(hào)-1