X Tutup
#include"ThreadCache.h" //从central control cache中获取一块内存 void* ThreadCache::GetMemFromCentalCache(size_t index,size_t memSize) { //central control cache中内存对象对应的索引和freelist中对应的索引应该是相同,直接由参数传过来,减少计算 //使用慢启动获取一批内存对象 size_t expectedNum = min(SizeCalculation::NumMoveSize(memSize), _freelist[index].MaxSize());//期望申请的内存对象个数 //去中心缓存中获取expectedNum个对象 void* start = nullptr; void* end = nullptr; //这里对内存大小需要向上对齐 size_t actualNum = CentralControlCache::GetInstance()->GetRangeMem(start, end, expectedNum, SizeCalculation::RoundUp(memSize)); //申请失败 assert(actualNum > 0); //如果您申请到的内存多余1个,将后边的挂起来,返回第一个 if (actualNum > 1) { _freelist[index].PushRange(Next(start), end, actualNum - 1); //将start的next置空 Next(start) = nullptr; } //慢启动增长:将最大值+1,下次申请时比这次申请的就多一个;否则表明已经到了最大值,就不在增加了 if (expectedNum == _freelist[index].MaxSize()) _freelist[index].SetMaxSize(expectedNum+1); //将第一个返回 return start; } //申请内存 void* ThreadCache::Allocate(size_t memSize) { assert(memSize <= THREAD_MAX_SIZE); //计算索引---内存对象在freelist数组中的索引 size_t freelistIndex = SizeCalculation::Index(memSize); if (_freelist[freelistIndex].empty()) { //在central control cache中申请 return GetMemFromCentalCache(freelistIndex,memSize); } else { //直接从链表中取一个内存对象返回 return _freelist[freelistIndex].pop(); } } //释放内存 void ThreadCache::DeAllocate(void* mem, size_t memSize) { //计算对应的索引 size_t index = SizeCalculation::Index(memSize); //将mem内存Push到_freelist中 _freelist[index].push(mem); //判断_freelist中的内存是否需要归还给centtral control cache中 if (_freelist[index].Size() >= _freelist[index].MaxSize()) { ListTooLong(_freelist[index], memSize); } } // 释放对象时,链表过长时,回收内存回到中心缓存 void ThreadCache::ListTooLong(FreeList& list, size_t memSize) { size_t batchNum = list.MaxSize(); void* start = nullptr; void* end = nullptr; //获取到maxsize个对象(_freelist中删除) list.PopRange(start, end, batchNum); //释放到central control cache中 CentralControlCache::GetInstance()->ReleaseListToSpans(start, memSize); }
X Tutup