高并发内存池: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;
};

感谢支持,长期连载

欢迎关注

相关推荐
Escalating_xu11 小时前
【Linux 网络编程】五种 I/O 模型与非阻塞 I/O:从“等数据”到正确处理 EAGAIN
java·linux·网络
程序猿乐锅12 小时前
万字详解Single-flight(单飞模式)
java·开发语言·分布式·后端·学习·single-flight
Highcharts.js12 小时前
React 中原生支持使用 JSX 组件配置自定义表格 Highcharts Grid
前端·javascript·react.js·前端框架·jsx·highcharts·自定义表格
Java后端的Ai之路12 小时前
【AIAgent开发】-Agent工具封装成CLI(纯干货!!!)
java·javascript·人工智能·agent·cli
薛定谔的猫-菜鸟程序员12 小时前
Electron开发超详细教程(从入门到放弃)
前端·javascript·electron
AntsData13 小时前
用 12K+ 条亚马逊评论信号,定位机械键盘下一版该改什么
java·大数据·计算机外设
code2cat13 小时前
【随笔】连续批处理:长短请求怎样在迭代之间补位
java·人工智能·后端·大语言模型·vllm
最强小杰13 小时前
DeepSeek V4 Flash + Codex CLI 接入教程:原生 Responses API 适配,从配置到跑通收藏这篇就够了(2026)
java·前端·python·ai
Flynn Liang13 小时前
Spring AI 2.0 深度解析:ChatClient、Advisor 链与 MCP——Java 工程师的 AI 落地最优解
java·人工智能·spring·大模型·架构设计·spring ai
灿飞13 小时前
Kotlin与Java虚拟机六:基础与类型系统:一切皆对象,但对象有代价
java·kotlin