01內存池設計

概述

  • 4kb內存對齊,內存分配以4kb爲基準.內存分配都是按照一定的值32,16,4等,少了也這樣分。內存的設計原理:就是指針得到不斷移動,設計到指針核心就移動來移到不同的內存區.連續的內存空間分配有申請必須有釋放對於內存操作.

重載全局運算符

/*
 * @Author: power
 * @Date: 2020-01-28 10:41:36
 * @LastEditTime : 2020-01-28 15:13:23
 * @LastEditors  : Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /test/Alloctor.cpp
 */
// #include "Alloctor.hpp"
#include <stdlib.h>
#include "MemoryPoll.hpp"
void* operator new(size_t nSize)
{
    return MemoryMgr::Instance().allocMem(nSize);
}
void operator delete(void* p)
{
    MemoryMgr::Instance().freeMem(p);
}
void* operator new[](size_t nSize)
{
    return MemoryMgr::Instance().allocMem(nSize);
}
void operator delete[](void* p)
{
    MemoryMgr::Instance().freeMem(p);
}
void* mem_alloc(size_t size)
{
    return malloc(size);
}
void mem_free(void *p)
{
    free(p);
}

編寫內存塊和內存管理工具

/*
 * @Author: power
 * @Date: 2020-01-28 11:05:02
 * @LastEditTime : 2020-01-28 14:42:11
 * @LastEditors  : Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /test/MemoryPoll.hpp
 */
#ifndef _MEMORYPOLL_H_
#define _MEMORYPOLL_H_
#define MAX_MEMORY_SZIE 128
#include <stdlib.h>
#include <assert.h>
#include <mutex>
#include <iostream>
class MemoryPoll;
class MemoryBlock
{
private:
    /* data */
    //預留字段
    char c1;
    char c2;
    char c3;
public:
    MemoryPoll* pAlloc;//所屬的內存池
    MemoryBlock* pNext;//下一塊位置
    int nID;//內存塊編號
    int nRef;//內存塊編號
    bool bPool;//是否在內存池中
};
class MemoryPoll
{
private:
    /* data */
public:
    MemoryPoll()
    {
        _pbuf = nullptr;
        _pHeader = nullptr;
        _nSize = 0;
        _nBlockSize = 0;
    }

    ~MemoryPoll()
    {
        if(_pbuf)
        free(_pbuf);
    }
    //內存池申請
    void* allocMemory(size_t nSize)
    {
        std::lock_guard<std::mutex> lg(_mutex);
        if(!_pbuf)
        {
            initMemory();
        }
        MemoryBlock* pReturn = nullptr;
        if(nullptr==_pHeader)
        {
            pReturn = (MemoryBlock*)malloc(nSize+sizeof(MemoryBlock));
            pReturn->bPool = false;
            pReturn->nID = -1;
            pReturn->nRef = 1;
            pReturn->pAlloc = nullptr;
            pReturn->pNext = nullptr;
        }
        else
        {
            pReturn = _pHeader;
            _pHeader= _pHeader->pNext;
            assert(0 == pReturn->nRef);
            pReturn->nRef = 1;
        }
        return ((char*)pReturn + sizeof(MemoryBlock));
        
    }
    void freeMemory(void* pMem)
    {
        MemoryBlock* pBlock = (MemoryBlock*)((char*)pMem-sizeof(MemoryBlock));
        assert(1 == pBlock->nRef);
        if(pBlock->bPool)
        {
            std::lock_guard<std::mutex> lg(_mutex);
            if(--pBlock->nRef !=0)
            {
                return;//被佔用
            }
            pBlock->pNext = _pHeader;
            _pHeader = pBlock;
        }
        else
        {
            if(--pBlock->nRef!=0)
            {
                return;
            }
            free(pBlock);
        }
        
    }
    //初始化內存池
    void initMemory()
    {
        //斷言
        assert(nullptr==_pbuf);
        if(_pbuf)
        return;
        //計算內存池的大小
        size_t realSize = _nSize + sizeof(MemoryBlock);//真實每塊內存的大小
        size_t bufSize = realSize*_nBlockSize;//內存池的總大小
        _pbuf =(char*)malloc(bufSize);
        //初始化內存池
        _pHeader = (MemoryBlock*)_pbuf;
        _pHeader->bPool = true;
        _pHeader->nID = 0;
        _pHeader->nRef = 0;
        _pHeader->pAlloc = this;
        _pHeader->pNext = nullptr;
        //遍歷內存塊進行初始化
        MemoryBlock* pTemp1 = _pHeader;
        for (size_t i = 1; i < _nBlockSize; i++)
        {
            MemoryBlock* pTemp2 = (MemoryBlock*) (_pbuf+i*realSize);
            pTemp2->nID = i;
            pTemp2->bPool = true;
            pTemp2->nRef = 0;
            pTemp2->pAlloc = this;
            pTemp2->pNext = nullptr;
            pTemp1->pNext = pTemp2;
            pTemp1 = pTemp2;

        }
        
    }
protected:
    //內存池地址即維護一塊大內存
    char* _pbuf;
    //首部位置
    MemoryBlock* _pHeader;
    //內存池的大小
    size_t _nSize;
    //內存單元的數量
    size_t _nBlockSize;
    std::mutex _mutex;
};

template<size_t nSize,size_t nBlockSize>
class MemoryAlloctor:public MemoryPoll
{
private:
    /* data */
public:
    MemoryAlloctor()
    {
        const size_t n = sizeof(void*);
        _nSize = (nSize/n)*n+(nSize % n ? n : 0);//規定以4的倍數分配內存空間
        _nBlockSize = nBlockSize;
    }
};
//內存池管理工具
class MemoryMgr
{
private:
    /* data */
    MemoryAlloctor<64,1000> _mem64;
    MemoryAlloctor<128,1000> _mem128;
    MemoryPoll* _szAlloc[MAX_MEMORY_SZIE+1];
public:
    MemoryMgr()
    {
        init_szAlloc(0,64,&_mem64);
        init_szAlloc(65,128,&_mem128);
    }
    ~MemoryMgr()
    {
        
    }
    static MemoryMgr& Instance()
    {
        static MemoryMgr mgr;
        std::cout<<"jinru"<<std::endl;
        return mgr;
    }
    void init_szAlloc(int nBegin,int nEnd,MemoryPoll* pMemA)
    {
        for (int i = nBegin; i <= nEnd; i++)
        {
            /* code */
            _szAlloc[i] = pMemA;
        }
        
    }
    void* allocMem(size_t nSize)
    {
        if(nSize <= MAX_MEMORY_SZIE)
        {
            return _szAlloc[nSize]->allocMemory(nSize);
        }
        else
        {
            MemoryBlock* pReturn = (MemoryBlock*)malloc(nSize+sizeof(MemoryBlock));
            pReturn->bPool = false;
            pReturn->nID = -1;
            pReturn->nRef = 1;
            pReturn->pAlloc = nullptr;
            pReturn->pNext = nullptr;
            return ((char*)pReturn+sizeof(MemoryBlock));
        }
        
    }
    //釋放內存
    void freeMem(void*pMem)
    {
        MemoryBlock * pBlock = (MemoryBlock*)((char*)pMem-sizeof(MemoryBlock));
        if (pBlock->bPool)
        {
            pBlock->pAlloc->freeMemory(pMem);
        }
        else
        {
            if(--pBlock->nRef == 0)
            {
                free(pBlock);
            }
        }
        
        
    }
};





#endif // !_MEMORYPOLL_H_

進行測試

/*
 * @Author: power
 * @Date: 2020-01-28 14:37:44
 * @LastEditTime : 2020-01-28 15:17:14
 * @LastEditors  : Please set LastEditors
 * @Description: In User Settings Edit
 * @FilePath: /test/MemoryTest.cpp
 */
#include <iostream>
#include "Alloctor.cpp"
int main(int argc, const char** argv) {

    int*p = new int(8);
    std::cout<<*p;
    return 0;
}

測試結果

輸出8

發佈了15 篇原創文章 · 獲贊 0 · 訪問量 840
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章