定长内存池设计

设计思想

先和系统申请一大块内存空间,然后每次用完用链表将回收的内存连起来,下次继续使用他们

固定大小的内存申请释放需求


特点:
1、性能达到极致
2、不考虑内存碎片等问题。

代码解读:

先设置三个成员memeory指向整体申请的大小,remainbytes指向剩余字节数,freelist指向归还的头节点

先判断remainbytes是否比要申请的size小,如果小那么就重新申请内存大小,如果申请失败则抛异常。

 申请成功则让memory转成obj的大小,取T个大小,判断一下T的size和void*的size哪个大,如果T的size小则取至少一个void*的大小,如果T的size大则取T的大小,方便后面链表的链接,objsize等于判断后的大小,让mem+obj=mem整个的剩余起始地址,remain的尺寸=remain-objsize

如果freelist中不等于空则优先调用freelist中的内存区域

首先先析构obj,再用链表将剩余的obj归还给freelist

freelist是个地址,取obj的头8位给freelist,然后再将freelist指针指向obj

 测试代码

#ifndef CONCURRENTMEMORYPOOL_OBJECTPOOL_H
#define CONCURRENTMEMORYPOOL_OBJECTPOOL_H

#include <iostream>
#include<time.h>
#include<vector>
using std::cout;
using std::endl;


template<class T>
class ObjectPool{
public:
    T* New(){
        //优先使用还回来的对象
        T*obj= nullptr;
        if(_freeList){
            void* next=*((void**)_freeList);
            obj=(T* )_freeList;
            _freeList=next;

        }else{
            // 剩余内存不够一个对象大小时候,重新开大块空间
            if(_remainBytes<sizeof(T)){
                _remainBytes=128*1024;
                _memory=(char*)malloc(_remainBytes);
                if(_memory== nullptr) {
                    throw std::bad_alloc();//抛异常
                    exit(-1);
                }
            }
            //走到这说明申请成功
            obj=(T*)_memory;//强转成需要的大小
            size_t objsize=sizeof(T)<sizeof (void*)?sizeof(void*):sizeof (T);
            _memory+=objsize;//当前还剩余的空间
            _remainBytes-=objsize;


        }
        //定位new,显示调用构造函数初始化,相当于在池子里开辟obj
        new(obj)T;

        return obj;

    }
    void Delete(T* obj){
        //  显示调用析构函数清理对象
        obj->~T();
        *(void**)obj=_freeList;
        _freeList=obj;

        //不需要判断直接插入freelist
//        if(_freeList== nullptr){
//            _freeList=obj;
//           *(void**)obj=nullptr;
//        }
    }

private:
    char* _memory= nullptr;//char好切字节,指向大块内存的指针
    size_t _remainBytes=0;//大块内存切分过程中的剩余字节数
    void* _freeList= nullptr;//还回来过程中链接的自由链表的头指针

};
struct TreeNode
{
    TreeNode()
            :_val(0)
            , _left(nullptr)
            , _right(nullptr)
    {

    }
    int _val;
    TreeNode* _left;
    TreeNode* _right;


};
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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值