《C++实战项目-高并发内存池》7.大块内存的申请与释放

💡Yupureki:个人主页

✨个人专栏:《C++》 《算法》《Linux系统编程》《高并发内存池》


🌸Yupureki🌸的简介:


目录

[1. 大块内存的申请](#1. 大块内存的申请)

[2. 大块内存的释放](#2. 大块内存的释放)


完整项目链接https://github.com/Yupureki-code/ConcurrentMemoryPool

1. 大块内存的申请

ThreadCache和CentralCache内部能够存储的最大内存块为256kb。如果进程申请了超过256kb的内存块时,应该越级直接向PageCache申请

这个判断应该在最开始的向ThreadCache申请资源环节进行

cpp 复制代码
static void* ConcurrentAlloc(size_t size)
{
	if (size > MAX_BYTES)//大于256kb
	{
		size_t alignSize = SizeClass::RoundUp(size);
		size_t kpage = alignSize >> PAGE_SHIFT;

		PageCache::GetInstance()->_pageMtx.lock();
		Span* span = PageCache::GetInstance()->NewSpan(kpage);//直接向PageCache申请
		span->_objSize = size;
		PageCache::GetInstance()->_pageMtx.unlock();

		void* ptr = (void*)(span->_pageId << PAGE_SHIFT);
		return ptr;
	}
	else
	{
		// 通过TLS 每个线程无锁的获取自己的专属的ThreadCache对象
		if (pTLSThreadCache == nullptr)
		{
			static ObjectPool<ThreadCache> tcPool;
			//pTLSThreadCache = new ThreadCache;
			pTLSThreadCache = tcPool.New();
		}

		//cout << std::this_thread::get_id() << ":" << pTLSThreadCache << endl;

		return pTLSThreadCache->Allocate(size);
	}	
}

同时PageCache内部能够存储的最大页数为128,因此有两种情况

  1. 内存块大于256kb 小于 128 * 8 kb,则可以在PageCache内部拿
  2. 如果大于128 * 8 kb,那么说明PageCache也做不到,应该越级向系统申请

因此当PageCache收到这个请求后,也应该做特殊对待

cpp 复制代码
// 获取一个K页的span
Span* PageCache::NewSpan(size_t k)
{
	assert(k > 0);

	// 大于128 page的直接向堆申请
	if (k > NPAGES-1)
	{
		void* ptr = SystemAlloc(k);
		//Span* span = new Span;
		Span* span = _spanPool.New();

		span->_pageId = (PAGE_ID)ptr >> PAGE_SHIFT;
		span->_n = k;

		_idSpanMap[span->_pageId] = span;
		return span;
	}
    .......
}

2. 大块内存的释放

当进程释放这个大块内存后,原来是向PageCache申请的,现在也应该直接向PageCache释放

cpp 复制代码
static void ConcurrentFree(void* ptr)
{
	Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr);
	size_t size = span->_objSize;

	if (size > MAX_BYTES)//释放大块内存
	{
		PageCache::GetInstance()->_pageMtx.lock();
		PageCache::GetInstance()->ReleaseSpanToPageCache(span);
		PageCache::GetInstance()->_pageMtx.unlock();
	}
	else
	{
		assert(pTLSThreadCache);
		pTLSThreadCache->Deallocate(ptr, size);
	}
}

同时PageCache最大只能存储128页的内存块,因此如果大于128 * 8 kb的大小,应该直接向系统释放

cpp 复制代码
void PageCache::ReleaseSpanToPageCache(Span* span)
{
	// 大于128 page的直接还给堆
	if (span->_n > NPAGES-1)
	{
		void* ptr = (void*)(span->_pageId << PAGE_SHIFT);
		SystemFree(ptr);
		//delete span;
		_spanPool.Delete(span);

		return;
	}
    ......
}
相关推荐
我不是疯子是傻子9 分钟前
串口通信数据帧粘包拆包再进化:基于 Qt 的滑动窗口与 CRC 校验实战
开发语言·qt
m0_5474866614 分钟前
《数据结构与算法》全套PPT课件2026(中国海洋大学)
数据结构·算法
程序员老陆18 分钟前
Qt中实现窗口真全屏(覆盖Windows任务栏)
开发语言·windows·qt
立少→万能汉编21 分钟前
用“立少→超文本”写静态网页,标签<倍>
服务器·前端·javascript
旖旎夜光24 分钟前
LeetCode 904:水果成篮(滑动窗口) —— 题解
数据结构·c++·算法·leetcode·滑动窗口
霸道流氓气质43 分钟前
Java中信号量(Semaphore):从本地到分布式
java·开发语言·分布式
怪奇云呼军1 小时前
G.711、Opus 和重采样会拖慢识别吗?闪电智能VoiceAgent 的音频入口怎么选
java·人工智能·python·算法·云计算·音视频
路溪非溪1 小时前
Python语言的执行流程总结
开发语言·python
民乐团扒谱机1 小时前
【超详解】量子克拉美罗下界QCRB:时延估计精度极限推导+MATLAB多场景绘图实战
开发语言·机器学习·matlab·量子力学·qcrb
笨鸟先飞,勤能补拙1 小时前
Web 服务器与计算机网络全景原理
运维·服务器·前端·网络·人工智能·计算机网络·web安全