原理

 还回来的内存用链表串联起来,称为自由链表
 内存块自身进行链接,前四个字节存下一个的地址
 
结构
template<class T>
class ObjectPool
{
public:
	T* New()
	{
		
	}
private:
	char* _memory = nullptr;  //方便切割
	void* _freeList = nullptr;
};
第一步:先给_memory搞一块大内存
	T* New()
	{
		if (_remainBytes <sizeof(T))  //剩余的内存不够分配一个T的大小,重开一个大空间
		{
			_remainBytes = 128 * 1024;
				_memory = (char*)malloc(_remainBytes); //分配初始的大内存128byte
			if (_memory == nullptr)
			{
				throw bad_alloc();
			}
		}
			T* obj = (T*)_memory;
			_memory += sizeof(T);
			_remainBytes -= sizeof(T);
			return obj;
	}
考虑对象的还回
前四/八个字节空间用来指向
 
 
 采用头插的方式
 
new从freeList中优先切出

T* New()
	{
		T* obj = nullptr;
		//优先利用freeList中的
		if (_freeList)
		{
			void* next = *((void**)_freeList);
			obj =(T*)_freeList;  //obj指向第一块
			_freeList = next;
			return obj;
		}
		else
		{
			if (_remainBytes < sizeof(T))  //剩余的内存不够分配一个T的大小,重开一个大空间
			{
				_remainBytes = 128 * 1024;
				_memory = (char*)malloc(_remainBytes); //分配初始的大内存128byte
				if (_memory == nullptr)
				{
					throw bad_alloc();
				}
			}
			obj = (T*)_memory;
			_memory += sizeof(T);
			_remainBytes -= sizeof(T);
			return obj;
		}
	}
平台冲突问题,申请值小于一个指针大小(64位平台,指针大小为8byte),则给一个指针。并且保证自由链表在链接时,空间至少能存进下一个对象的地址。
加上obj初始化,显示调用析构函数清理对象(T)
#pragma once
#include <iostream>
using std::cout;
using std::endl;
using std::bad_alloc;
//定长内存池
//template<size_t N>
//class ObjectPool
//{};
template<class T>
class ObjectPool
{
public:
	T* New()
	{
		T* obj = nullptr;
		//优先利用freeList中的
		if (_freeList)
		{
			void* next = *((void**)_freeList);
			obj =(T*)_freeList;  //obj指向第一块
			_freeList = next;
		}
		else
		{
			if (_remainBytes < sizeof(T))  //剩余的内存不够分配一个T的大小,重开一个大空间
			{
				_remainBytes = 128 * 1024;
				_memory = (char*)malloc(_remainBytes); //分配初始的大内存128byte
				if (_memory == nullptr)
				{
					throw bad_alloc();
				}
			}
			obj = (T*)_memory;
			size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
			_memory += objSize;
			_remainBytes -= objSize;
		}
		//定位new,显示调用T的构造函数初始化
		new(obj)T;
		return obj;
	}
	void Delete(T* obj)
	{
		//显示调用析构函数清理对象(T)
		obj->~T();
		//头插
		*(void**)obj = _freeList;
		_freeList = obj;
	} 
private:
	char* _memory = nullptr;  //方便切割  指向大块内存的指针
	size_t _remainBytes = 0;  //大块内存在切分过程中剩余字节数
	void* _freeList = nullptr;//还回来的内存链接到的自由链表的头指针
};
测试性能
用数结构分别对比vector容器下(malloc)std::vector<TreeNode*>和此内存池下ObjectPool的运行时间
 ConcurrentMemoryPoll.cpp
// ConcurrentMemoryPool.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include "ObjectPool.h"
int main()
{
    TestObjectPool();
    return 0;
}
ObjectPool.h
#pragma once
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::bad_alloc;
//定长内存池
//template<size_t N>
//class ObjectPool
//{};
template<class T>
class ObjectPool
{
public:
	T* New()
	{
		T* obj = nullptr;
		//优先利用freeList中的
		if (_freeList)
		{
			void* next = *((void**)_freeList);
			obj =(T*)_freeList;  //obj指向第一块
			_freeList = next;
		}
		else
		{
			if (_remainBytes < sizeof(T))  //剩余的内存不够分配一个T的大小,重开一个大空间
			{
				_remainBytes = 128 * 1024;
				_memory = (char*)malloc(_remainBytes); //分配初始的大内存128byte
				if (_memory == nullptr)
				{
					throw bad_alloc();
				}
			}
			obj = (T*)_memory;
			size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
			_memory += objSize;
			_remainBytes -= objSize;
		}
		//定位new,显示调用T的构造函数初始化
		new(obj)T;
		return obj;
	}
	void Delete(T* obj)
	{
		//显示调用析构函数清理对象(T)
		obj->~T();
		//头插
		*(void**)obj = _freeList;
		_freeList = obj;
	} 
private:
	char* _memory = nullptr;  //方便切割  指向大块内存的指针
	size_t _remainBytes = 0;  //大块内存在切分过程中剩余字节数
	void* _freeList = nullptr;//还回来的内存链接到的自由链表的头指针
};
struct TreeNode
{
	int _val;
	TreeNode* _left;
	TreeNode* _right;
	TreeNode()
		:_val(0)
		, _left(nullptr)
		, _right(nullptr)
	{}
};
void TestObjectPool()
{
	// 申请释放的轮次
	const size_t Rounds = 5;
	// 每轮申请释放多少次
	const size_t N = 100000;
	std::vector<TreeNode*> v1;
	v1.reserve(N);
	size_t begin1 = clock();
	for (size_t j = 0; j < Rounds; ++j)
	{
		for (int i = 0; i < N; ++i)
		{
			v1.push_back(new TreeNode);
		}
		for (int i = 0; i < N; ++i)
		{
			delete v1[i];
		}
		v1.clear();
	}
	size_t end1 = clock();
	std::vector<TreeNode*> v2;
	v2.reserve(N);
	ObjectPool<TreeNode> TNPool;
	size_t begin2 = clock();
	for (size_t j = 0; j < Rounds; ++j)
	{
		for (int i = 0; i < N; ++i)
		{
			v2.push_back(TNPool.New());
		}
		for (int i = 0; i < N; ++i)
		{
			TNPool.Delete(v2[i]);
		}
		v2.clear();
	}
	size_t end2 = clock();
	cout << "new cost time:" << end1 - begin1 << endl;
	cout << "object pool cost time:" << end2 - begin2 << endl;
}
Debug版本
 32位
 
 64位
 
Release版本
 32位
 
 64位
 
 清晰看出,ConcurrentMemoryPool的高效



















