游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1806|回复: 3

内存池模型

[复制链接]

80

主题

173

帖子

189

积分

注册会员

Rank: 2

积分
189
发表于 2006-5-15 13:12:00 | 显示全部楼层 |阅读模式
#ifndef _MEMPOOL_H
#define _MEMPOOL_H
#include <Windows.h>
/////////////////////////////////////////////////////////////////   
//   
//     class   CMyCriticalSection   
//   
/********************************************************************
created: 2004/11/29
created: 29:11:2004   16:02
filename:  ..\memory pool\test\cmempool.h
file path: ..\memory pool\test
file base: cmempool
file ext: h
author:  David

purpose: 同等大小的小对象如果频繁的动态申请与释放(eg: s
erver),必然会导致系统产生大量的内存碎片,这样
当系统长时间的运行后,就会因为大量的内存碎片而
导致无法再分配出内存,这样我们的软件就会变的不
稳定,而且频繁的new和delete会导致效率低下,因此
需要有自己内存管理。下面的类就是一个简单的内存
管理。
*********************************************************************/
//修改者申明:
//内存池其实管理指向内存的指针,来达到管理内存目的。
//
//关键区锁
class CLock
{
        CRITICAL_SECTION criSection;
public:
        CLock()    { InitializeCriticalSection( &criSection ); }
        ~CLock()   { DeleteCriticalSection( &criSection );     }
        void Lock() { EnterCriticalSection( &criSection );      }
        void Unlock() { LeaveCriticalSection( &criSection );      }
};

//指针结构
template <class CNode>
struct Mem_Pool_Node
{
        union {
                char Obj[sizeof(CNode)];
                Mem_Pool_Node *m_pNext;
        };
};
//主要模块

template <class CNode>
class CMemPool
{
        typedef Mem_Pool_Node<CNode>*  Mem_Pool_Node_Type;
public:
        CMemPool()
        {
                m_pListFreePool = NULL;//头指针指向空
                m_nInuse = 0;
                m_nFree = 0;
        };

        virtual ~CMemPool()
        {
                Mem_Pool_Node_Type pPreNode= NULL;
                Mem_Pool_Node_Type pNode= NULL;

                m_Lock.Lock();
                //释放分配的节点的指针指向的内存:注意不是释放节点
                //释放的过程如下:
                //m_pListFreePool->[2]->[1]->[0]->NULL
                //pPreNode,把最前边的哪个元素隔离出来释放。
                //pNode指向当前的m_pListFreePool->[1];
                //如此循环释放掉所有接点

                pPreNode = m_pListFreePool;
                pNode = m_pListFreePool;  
                while (NULL != pNode)
                {
                        pPreNode = pNode;
                        pNode = pNode->m_pNext;

                        delete pPreNode;
                        pPreNode = NULL;
                }
                m_Lock.Unlock();
        };
        //这个函数的说明:
        /*

        空闲内存的链表结构如下
        m_pListFreePool->[2]->[1]->[0]->NULL;
        if (NULL == m_pListFreePool) 表明此时的链表结构如下
        m_pListFreePool->NULL;我们已经分配的内存全部在使用
        可以使用内存为零
        所以需要重新分配内存。
        else 链表结构如下的时候:
        m_pListFreePool ->[n] .....[2]->[1]->[0]->NULL;
        的时候表明有我们已经分配的内存有很多空余,所以不需要重新分配
        只需要从m_pListFreePool ->[n] .....[2]->[1]->[0]->NULL;取出
        [n]使用就可以了。同时把空闲内存链表修改如下
        m_pListFreePool ->[n-1] .....[2]->[1]->[0]->NULL
        */
       

        CNode *Allocate()
        {
                void *p = NULL;
                Mem_Pool_Node_Type pNode= NULL;

                if (NULL == m_pListFreePool)
                {
                        try
                        {
                                p = (:perator new(sizeof(CNode)));
                        }
                        catch (...)
                        {
                                if (p != NULL)
                                {
                                        ::operator delete ((CNode *)(p));
                                        p = NULL;
                                }

                                return NULL;
                        }

                        m_Lock.Lock();
                        m_nInuse++;
                        m_Lock.Unlock();
                }
                else
                {
                        m_Lock.Lock();
                        pNode = m_pListFreePool;
                        m_pListFreePool = m_pListFreePool->m_pNext;

                        p = pNode;

                        m_nFree--;
                        m_nInuse++;
                        m_Lock.Unlock();
                }

                return static_cast<CNode *>(p);
        };
        /*空闲内存的链表结构如下
                m_pListFreePool->[2]->[1]->[0]->NULL;
                /*
                //这个函数是上边哪个函数的反过程
                //说明:
                /*
        if (NULL == m_pListFreePool) 表明此时的链表结构如下
                m_pListFreePool->NULL;也就是说我们已经分配的内存全部在使用,空闲内存为空
                这个时候把p转化成一个Mem_Pool_Node节点插入列表头 并且mem_pool_Node->next=NULL。使
                m_pListFreePool->next指向p;这其实是一个简单的列表头插入操作
        else 链表结构如下的时候,即:要在[n]->前边插入一个接点
        m_pListFreePool ->[n] .....[2]->[1]->[0]->NULL;
        我们插入一个接点
                只需要从m_pListFreePool ->[n] .....[2]->[1]->[0]->NULL;插入
                [n+1]就可以了。同时把空闲内存链表修改如下
                m_pListFreePool ->[n+1]->[n] .....[2]->[1]->[0]->NULL
                表明现在有n+1块内存可以自由使用。
                */


        void Release(void *p)
        {
                if (NULL == p)
                {
                        return;
                }

                m_Lock.Lock();
                if (NULL == m_pListFreePool)
                {
                        m_pListFreePool = static_cast<Mem_Pool_Node_Type>(p);
                        m_pListFreePool->m_pNext = NULL;
                }
                else
                {
                        (static_cast<Mem_Pool_Node_Type>(p))->m_pNext = m_pListFreePool;
                        m_pListFreePool = static_cast<Mem_Pool_Node_Type>(p);
                }

                m_nInuse--;
                m_nFree++;
                m_Lock.Unlock();
        };

        void GetInfo(int &inuse, int &free)
        {
                inuse = m_nInuse;
                free = m_nFree;
        };
private:
        CLock m_Lock;

        int m_nInuse;
        int m_nFree;
        Mem_Pool_Node_Type m_pListFreePool;
};
#endif

80

主题

173

帖子

189

积分

注册会员

Rank: 2

积分
189
 楼主| 发表于 2006-5-15 13:14:00 | 显示全部楼层

Re:内存池模型


#ifndef _MEM_POOL_TEST_
#define _MEM_POOL_TEST_
/********************************************************************
created: 2004/11/29
created: 29:11:2004   15:27
filename:  e:\复用\memory pool\test\cmempooltest.h
file path: e:\复用\memory pool\test
file base: cmempooltest
file ext: h
author:  David

purpose: 这是一个测试内存池类的类,主要用到的类为:
1.CMemPool--CMemPool.h主要用于对内存池的管理(Allocate and Release)的
template, 适用于每个节点的大小都相等的情况。
2.CLock--Lock.h主要被CMemPool内部所用,同步CMemPool内部inuse链表和free
链表。
3.CMemPoolTest CBuffer--用于测试CMemPool的类。一个CMemPoolTest实例模拟
一个网络session,因为该类实例有可能会频繁生成和释放,故需采用内存池,
而每个实例管理自己的缓冲区列表,而缓冲区列表也有可能会频繁生成和释放
掉,故也采用内存池,这样就有可能出现内存池嵌套现象,这两个类就是用来
模拟CMemPool嵌套的情况的,试验结果良好。
4.注意点:使用类CMemPool的类必须重装new和delete,在new中从内存池Allocate
内存,
而在delete中Release内存,归还给内存池。内存池应该属于类的资产,而不是
对象的资产,故为static类型的成员。
5.建议:对于同类对象频繁生成于释放的情况,建议使用内存池,这样可以防止内存
碎片和有助于程序的稳定。
*********************************************************************/
#include<iostream>
#include  <list>
#include "memoryspool.h"
using namespace std;

class CBuffer
{
public:
        CBuffer();
        virtual ~CBuffer();

        static void* operator new(size_t);
        static void operator delete(void*);
private:
        int m_nBufLen;
        char m_pBuffer[2048];
        static CMemPool<CBuffer> m_MemPool;
};

class CMemPoolTest
{
public:
        CMemPoolTest();
        virtual ~CMemPoolTest();

        static void* operator new(size_t);
        static void operator delete(void*);


        void SetBuffer();
private:

        static CMemPool<CMemPoolTest> m_MemPool;

        list<CBuffer *> m_BufferList;
};

#endif

80

主题

173

帖子

189

积分

注册会员

Rank: 2

积分
189
 楼主| 发表于 2006-5-15 13:14:00 | 显示全部楼层

Re:内存池模型

//.cpp
#include "MemPoolTest.h"
CBuffer::CBuffer()
{
}

CBuffer::~CBuffer()
{
        cout << "~CBuffer" << endl;
}

void *CBuffer:perator new(size_t)
{
        CBuffer *p = NULL;

        p = static_cast<CBuffer*>(m_MemPool.Allocate());

        int m_nInuse, m_nFree;
        m_MemPool.GetInfo(m_nInuse, m_nFree);
        cout << "CBuffer Allocate m_nInuse is " << m_nInuse << " m_nFree is "<< m_nFree << endl;
        return p;
}

void CBuffer::operator delete(void *deadobject)
{
        m_MemPool.Release((CBuffer *)deadobject);

        int m_nInuse, m_nFree;
        m_MemPool.GetInfo(m_nInuse, m_nFree);
        cout << "CBuffer Release m_nInuse is " << m_nInuse << " m_nFree is "<< m_nFree << endl;
}

CMemPoolTest::CMemPoolTest()
{

}

CMemPoolTest::~CMemPoolTest()
{
        list<CBuffer*>::const_iterator pos;
        for(pos = m_BufferList.begin(); pos != m_BufferList.end(); ++pos){
                delete (CBuffer *)(*pos);
        }
        m_BufferList.clear();
}

void *CMemPoolTest::operator new(size_t)
{
        CMemPoolTest *p = NULL;

        p = static_cast<CMemPoolTest*>(m_MemPool.Allocate());

        /*
        int m_nInuse, m_nFree;
        m_MemPool.GetInfo(m_nInuse, m_nFree);
        cout << "Allocate m_nInuse is " << m_nInuse << " m_nFree is "<< m_nFree << endl;
        */
        return p;
}

void CMemPoolTest::operator delete(void *deadobject)
{
        m_MemPool.Release((CMemPoolTest *)deadobject);

        /*
        int m_nInuse, m_nFree;
        m_MemPool.GetInfo(m_nInuse, m_nFree);
        cout << "Release m_nInuse is " << m_nInuse << " m_nFree is "<< m_nFree << endl;
        */

}


void CMemPoolTest::SetBuffer()
{
        CBuffer *p = NULL;
        p = new CBuffer();

        m_BufferList.push_back(p);
}

80

主题

173

帖子

189

积分

注册会员

Rank: 2

积分
189
 楼主| 发表于 2006-5-15 13:15:00 | 显示全部楼层

Re:内存池模型

#include  <list>
#include "MemPoolTest.h"
CMemPool<CMemPoolTest> CMemPoolTest::m_MemPool;//fixed memory manager
CMemPool<CBuffer> CBuffer::m_MemPool;//fixed memory manager
int main(void)
{
        //test CMemPool
        int i = 0;
        CMemPoolTest *test[1000];
        for(i = 0; i < 10; i++)
        {
                test = new CMemPoolTest;
                test->SetBuffer();
        }

        for(i = 0; i < 10; i++)
        {
                if (test != NULL)
                {
                        delete test;
                        test = NULL;
                }
        }
        return 0;
}
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-24 12:53

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表