程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> 內存池的C++實現(可能還有小bug)

內存池的C++實現(可能還有小bug)

編輯:關於C++

最近在學習c++程序性能優化,讀到內存池部分。自己動手寫了一個,小小測試了一下應 該沒有問題。

內存塊MemoryBlock聲明文件

MemoryBlock.h

#pragma once
#define USHORT unsigned short
#define ULONG unsigned long
#include <iostream>
using namespace std;
//內存塊
struct MemoryBlock
{
    USHORT m_nSize;//可分配內存總大小
    USHORT m_nFree;//可分配內存單元數目
    USHORT m_nFirst;//第一個可用的內存單元位置
    MemoryBlock* m_pNext;//指向下一個內存塊
    char m_data[1];
    void* operator new(size_t,const USHORT& sum,const USHORT& unit_size)
    {
        return ::operator new(sizeof(MemoryBlock)+sum*unit_size);//申請一 個內存塊空間
    }
    void operator delete(void* del,size_t)
    {
        ::operator delete(del);//刪除內存塊空間
    }
    MemoryBlock(const USHORT& sum,const USHORT& unit_size)
        :m_nSize(sum*unit_size),m_nFree(sum-1),m_nFirst(1),m_pNext(0)
    {
        char* pData=m_data;
        for(int i=1;i<sum;i++) //初始化1到sum-1指向
        {
            *reinterpret_cast<USHORT*>(pData)=i;
            pData+=unit_size;
        }
    }
    ~MemoryBlock(){}

};

內存池MemoryPool聲明文件

MemoryPool.h

#pragma once
#include "MemoryBlock.h"

//內存池 a very good memory manager
class MemoryPool
{
private:
    USHORT m_nUnitSize;//一個可分配單元的大小
    USHORT m_nInitSize;//第一個可分配空間數目
    USHORT m_nGrowSize;//新增的可分配空間數目
    MemoryBlock* m_pFirst;//指向第一個內存塊
public:
    //單元大小,第一個內存塊的可分配空間數目,第二個內存塊之後的可分配空間數目
    MemoryPool(const USHORT& unit_size,const USHORT& init_size=2048,const USHORT& grow_size=1024);
    ~MemoryPool(void);
    void* Alloc();//分配內存
    void Free(void* pfree);//回收內存
    void FreeMemoryBlock(MemoryBlock *pblock);//銷毀
};

內存池MemoryPool實現文件

MemoryPool.cpp

#include "MemoryPool.h"

const USHORT MEMPOOL_ALIGNMENT=2;


MemoryPool::MemoryPool(const USHORT &unit_size, const USHORT &init_size, const USHORT &grow_size)
    :m_pFirst(0),
     m_nInitSize(init_size),
     m_nGrowSize(grow_size)
{
    if(unit_size>4)
    {
        m_nUnitSize = (unit_size + (MEMPOOL_ALIGNMENT-1)) & ~ (MEMPOOL_ALIGNMENT-1);
        //m_nUnitSize 取整到大於unit_size的最大的MEMPOOL_ALIGNMENT的倍 數.
        //令人糾結的注釋
    }
    else if(unit_size>=2)
        m_nUnitSize=4;
    else
        m_nUnitSize=2;
}

void* MemoryPool::Alloc()
{
    if(!m_pFirst) //如果是第一次申請
    {
        MemoryBlock* pmb_first=new (m_nInitSize,m_nUnitSize)MemoryBlock (m_nInitSize,m_nUnitSize);//14日凌晨至此
        m_pFirst=pmb_first;
        return (void*)pmb_first->m_data;
    }
    MemoryBlock* pmb_block=m_pFirst;
    while(pmb_block&&pmb_block->m_nFree==0) //pmb_block沒走到最後 並且當前block沒有可分配結點
    {
        pmb_block=pmb_block->m_pNext;//往後走吧。
    }
    if(pmb_block) //如果找到可分配結點的block
    {
        char* pfree=pmb_block->m_data+(pmb_block- >m_nFirst*m_nUnitSize);
        pmb_block->m_nFirst=*((USHORT*)pfree);
        pmb_block->m_nFree--;//可分配節點自減
        return (void*)pfree;
    }
    else//如果找不到,此時pmb_block值為0
    {
        if(m_nGrowSize==NULL)
            return NULL;
        pmb_block=new (m_nGrowSize,m_nUnitSize)MemoryBlock (m_nGrowSize,m_nUnitSize);
        if(!pmb_block) //new不成功
            return NULL;
        pmb_block->m_pNext=m_pFirst;//把新建的block放到最前吧
        m_pFirst=pmb_block;
        return (void*)pmb_block->m_data;
    }
}

void MemoryPool::Free(void* pfree)
{
    if(m_pFirst==NULL)
        return;
    MemoryBlock* pmb_block=m_pFirst;
    MemoryBlock* pmb_preblock=m_pFirst;
    while((ULONG)pfree<(ULONG)pmb_block->m_data||
        (ULONG)pfree>(ULONG)(pmb_block->m_data+pmb_block- >m_nSize)) //pfree不在當前block中
    {
        pmb_preblock=pmb_block;//前一個block塊
        pmb_block=pmb_block->m_pNext;
        if(!pmb_block)
            return;
    }
    pmb_block->m_nFree++;//可分配數目+1
    *((USHORT*)pfree)=pmb_block->m_nFirst;
    pmb_block->m_nFirst=(USHORT)((ULONG)pfree-(ULONG)pmb_block- >m_data)/m_nUnitSize;
    if(pmb_block->m_nFree*m_nUnitSize==pmb_block->m_nSize) //如何該鏈塊 為空
    {
        pmb_preblock->m_pNext=pmb_block->m_pNext;
        if((ULONG)pmb_preblock==(ULONG)m_pFirst)
            m_pFirst=NULL;
        delete pmb_block;
    }
}

MemoryPool::~MemoryPool(void)
{
    if(m_pFirst)
        FreeMemoryBlock(m_pFirst);
}


void MemoryPool::FreeMemoryBlock(MemoryBlock *pblock)
{
    if(pblock->m_pNext)
        FreeMemoryBlock(pblock->m_pNext);
    delete pblock;
    pblock=NULL;
}

Test.cpp

#include "MemoryPool.h"
#include "time.h"

void performance_old()
{
    clock_t start,stop;
    start = clock();//開始時間
    int i,b=0;
    for(i=0;i<=100000;i++)
    {
      int* p=new int;
    }

    cout<<"Without MemoryPool:"<< (double) (clock()-start)<<"ms"<<endl;//輸出
}

void memory()
{
    clock_t start;
    start = clock();//開始時間
    MemoryPool mp(sizeof(int),10000,500);
    int i=0;
    for(i=0;i<=100000;i++)
    {
      int* p=(int*)mp.Alloc();
    }

    cout<<"Using MemoryPool:"<<(double)(clock()-start) <<"ms";//輸出
}
int main()
{
    performance_old();
    memory();//內存池
    system("pause");
        return 0;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved