C++定长内存块的完成
内存池
内存池直接就是是指程序预先从操作系统 申请一块足够大内存 ,此后,当软件中需要申请内存的时候,不向操作系统申请,而是 直接从内存池中获取 ;
同理,当 **软件释放内存**的时候,并不真正将内存返回给操作系统,而是返回内存池。当程序退出( 或者特定时间 ) 时,内存池才将之前申请的内存真正释放。
程序关键
在进行地址归还的时候,必须要利用二级指针,因为获取到头部指针后需要记录下一个内存块的地址,这句话是理解下方程序的关键。
#
pragma once
#
include <iostream>
#
include <vector>
#
include <time.h>
using std::cout;
using std::endl;
//定长内存池
//template<size_t N>//非类型模板参数
//class ObjectPool
//{};
//定长内存池
template<
class T>
class ObjectPool
{
public:
T* New(
) {
size_t objsize =
sizeof(T) <
sizeof(
void*
) ?
sizeof(
void*
) :
sizeof(T)
;
T* obj = NULL
;
// step2:申请空间有限从回收链表_freeList里拿
if (_freeList) {
//_freeList每个固定大小的头部字节中都有下一块内存的地址
obj = (T*
)_freeList;
_freeList = *(
void**
)obj;
}
else {
// step1
// 小于1个指针给1个指针的大小
if (_remainBytes < objsize) {
_remainBytes = 128 * 1024
;
_memeory = (
char*
)malloc(_remainBytes)
;
// 开个128kb的空间
if (_memccpy == NULL
) {
throw std::bad_alloc(
)
;
// 直接抛出异常
}
}
obj = (T*
)_memeory;
_memeory += objsize;
_remainBytes -= objsize;
}
new(obj)T;
// 定位new,就是初始化这段空间
return obj;
}
void Delete(T* obj) {
// step1
// 将这些空间一一连接起来,回收并利用
obj->
~T(
)
;
// 显示调用析构函数
*(
void**
)obj = _freeList;
// *(void**)解引用就是void*的大小,也就是一个指针的大小
//头插入
_freeList = obj;
}
private:
char* _memeory = NULL
;
// 指向内存块 头部 的指针
size_t _remainBytes = 0
;
// 指向内存块 剩余 的指针
void* _freeList = NULL
;
// 指向回收链表的 头指针
}
;
struct TreeNode
{
int _val;
TreeNode* _left;
TreeNode* _right;
TreeNode(
)
:_val(0
)
, _left(
nullptr
)
, _right(
nullptr
)
{
}
}
;
void TestObjectPool(
)
{
// 申请释放的轮次
const size_t Rounds = 3
;
// 每轮申请释放多少次
const size_t N = 10000
;
//1w
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(
)
;
ObjectPool<TreeNode> TNPool;
std::vector<TreeNode*> v2;
v2.reserve(N)
;
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;
}

能够看到效率的提升

浙公网安备 33010602011771号