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

感谢支持,长期连载

欢迎关注

相关推荐
子兮曰3 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
小羊没烦恼!3 天前
微服务化的基石——持续集成
java·大数据·word·powerpoint·.net
子兮曰3 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
俊昭喜喜里3 天前
java中的继承和多态的区别
java
小羊没烦恼!3 天前
初探性能优化——2个月到4小时的性能提升
java·开发语言·windows·算法·c#
前端小万3 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝3 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
譕痕3 天前
JSONObject与JSONArray封装数据格式区别
java·json
胡写代码3 天前
别再前后端各写一套表单校验了
java·后端
小鱼能吃糖3 天前
缺陷修复总览 · mall电商项目:5类缺陷,1个病根,4个业务域
java·电商