高并发内存池:Part-1——定长内存池

@bit::Shadow
✧(≖ ◡ ≖✿

目录

定长内存池

一:New()的初步设计

二:Delete()的设计

为什么不回退_memory?

完整代码gitee


定长内存池

有效、可分配内存块有两部分

1.有效内存池块。

2.自由链表管理区域。

构造函数

划分128kB给ObjectPool对象,异常抛出std::bad_alloc()。

New:为特定类型通过自由链表存储的/池内,分配固定空间大小。

Delete(const T* t):销毁指定目标。

一:New()的初步设计

_remainBytes:内存块内(自由链表内不计入大小)的剩余字节。

cpp 复制代码
//申请
T* New()
{
	int _sz = sizeof(T);
	//块内分配
	if (_remainBytes <= _sz)
	{
		//剩余不足,新开大块
		Alloc();//内存碎片问题不计
	}
	T* obj = (T*)_memory;
	_memory += _sz;
	_remainBytes -= _sz;

	return obj;
}

初步架构:

cpp 复制代码
template<typename T>
class ObjectPool//无并发性,外界统一接口?
{
private:
	void Alloc()//bool?抛异常与bool分隔。bool会增加处理成本
	{
		//划分块
		_memory = (char*)malloc(128 * 1024);//1.此处malloc不够纯粹,"其底层封装"(划掉)
								//※			//2.使用SystemAlloc更纯粹,后期对比效率时替换
		if (!_memory)
			throw std::bad_alloc();//大块划分失败,怎么捕捉?与构造函数无关?
		_remainBytes = 128 * 1024;//※
	}

public:
	ObjectPool()
		:_memory(nullptr), _remainBytes(0)
	{ 
		Alloc();
	}
	//**成员先走初始化列表,后走函数体内**

	//申请
	T* New()
	{
		int _sz = sizeof(T);
		//块内分配
		if (_remainBytes <= _sz)
		{
			//剩余不足,新开大块
			Alloc();//内存碎片问题不计
		}
		T* obj = (T*)_memory;
		_memory += _sz;
		_remainBytes -= _sz;
        
        return obj;
	}
private:
	char* _memory;//内存块头指针(128kB)
	int _remainBytes;//内存块内(自由链表内不计入大小)的剩余字节
};

二:Delete()的设计

被删除任务删除头插进自由链表,由_freeList管理。

为什么不回退_memory?

销毁对象内存不一定连续。

设计图示

cpp 复制代码
//释放,自由链表回收♻️
void Delete(const T* t)
{
	//头插
	*(void**)t = _freeList;
	//_freeList = t;//原因分析
	_freeList = const_cast<T*>(t);
}

✨亮点:

1.为兼容x64、x86系统使用指针这一随系统大小变换的类型作为,限制访问区域。

2.const_cast<template T> (T t); 去const属性 // 非std域!!

完整代码gitee

cpp 复制代码
#pragma once
//using namespace std::
#include<iostream>

/*
设计原则:
1.模板元编程。基于T大小申请、管理内存块。
意味着:
单一类型对象,New固定T大小无法指定。不像(void*) maollc(sizeof(size_t size))
2.定长内存池设计的目标是:体会"池化技术",这一高效、广泛应用技术的底层设计原理。

//严格遵循"高内聚,低耦合"特性
*/
template<typename T>
class ObjectPool//无并发性
{
private:
	void Alloc()//bool?抛异常与bool分隔。bool会增加处理成本
	{
		//划分块
		_memory = (char*)malloc(128 * 1024);//1.此处malloc不够纯粹,"其底层封装"(划掉)
								//※			//2.使用SystemAlloc更纯粹,后期对比效率时替换
		if (!_memory)
			throw std::bad_alloc();//大块划分失败,怎么捕捉?与构造函数无关?
		_remainBytes = 128 * 1024;//※
	}

	T* FreeAlloc()
	{
		//自由链表分配
		//if (!_freeList)//err
		if (_freeList)
		{
			T* obj = _freeList;
			//头删
			_freeList = *(void**)_freeList;

			_remainBytes = _remainBytes;
			return obj;
		}
		return nullptr;
	}
public:
	ObjectPool()
		:_memory(nullptr), _remainBytes(0), _freeList(nullptr)
	{ 
		Alloc();
	}
	//**成员先走初始化列表,后走函数体内**

	//申请
	T* New()
	{
		//1.自由链表分配
		return FreeAlloc();

		//int _sz = sizeof(T);因为自由链表要管理,所以至少给4/8
		int _sz = sizeof(T) >= sizeof(T*) ? sizeof(T) : sizeof(T*);

		//dpsk:一个类型T*的指针管理T的空间与管理4T空间有什么区别?
		// 访问限制、算术法固定
		
		//2.块内分配
		if (_remainBytes <= _sz)
		{
			//剩余不足,新开大块
			Alloc();//内存碎片问题不计
		}
		T* obj = (T*)_memory;//
		_memory += _sz;
		_remainBytes -= _sz;

		return obj;
	}

    //释放,自由链表回收♻️
	void Delete(const T* t)
	{
		//头插
		*(void**)t = _freeList;
		//_freeList = t;//原因分析
		_freeList = const_cast<T*>(t);
	}
private:
	char* _memory;//内存块头指针(128kB)
	int _remainBytes;//内存块内(自由链表内不计入大小)的剩余字节

	T* _freeList;//自由链表头
};

//测试类型T
class TreeNode
{
private:
	int _val;
	TreeNode* _left;
	TreeNode* _right;
};

感谢支持,长期连载

欢迎关注

相关推荐
GuWenyue9 小时前
90%Node新手踩坑!path+fs两大内置模块完整实战,3种异步写法彻底告别回调地狱
前端
国服第二切图仔9 小时前
17-config命令 - 配置管理系统
java·前端·javascript
GuWenyue9 小时前
放弃云端API!5套技术栈实战WebGPU端侧AI,前端独立跑本地大模型,省成本还保隐私
前端·数据库·人工智能
胡萝卜术18 小时前
当大模型遇上浏览器:用 React + WebGPU 在前端跑通 DeepSeek-R1 的实战笔记
前端·javascript·面试
不好听61318 小时前
Tailwind CSS 原子化 CSS 完全入门:为什么现代前端开发都在用?
前端·css
人间凡尔赛18 小时前
Next.js 16 生产级实战:Cache Components + View Transitions 完整指南
开发语言·javascript·ecmascript
触底反弹18 小时前
🔥 React 零基础入门(上):环境搭建 + JSX 深度解析
前端·react.js·typescript
why技术18 小时前
分享一套我一直在使用的 AICoding 组合拳,小而美的典范。
前端·后端·ai编程
架构源启18 小时前
文档接入与智能解析:基于 Spring AI 1.1.x 的多格式解析、版面理解与结构化抽取
java·人工智能·spring