青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

內存池設計


       也許有人會問:內存池是什么呢? 主要用來干什么的?
     大家都知道,C++可以使用指針來操作堆內存以獲得高效率的內存訪問,一般會使用全局new, delete的內存管理函數來申請和分配內存,但在大量使用內存分配的程序里----比如:網絡游戲服務器的消息,每一條消息就分配一塊內存,等消息處理完后,又要釋放內存,這樣來來回回的new, delete操作,效率會大大折扣,因為new,delete函數不可能預先知道你的對象要分配多大空間,每一個都要從當前的堆中尋找一塊可用的空間來分配一個對象,最要命的是當你delete后,內存還要重新整理內存塊,這樣頻繁操作將造成低效率結果。
  于是,一個新的思想誕生了,如果當你滿足以下條件時,你可以使用內存池來提高效率:
       (1) 當你頻繁地操作一類對象時,即你老是new 和 delete
       (2) 當你知道使用一類對象的最大對象數時
      你可以使用內存池,它是預先分配一定數量的一段內存空間,這一段空間預先分配了某類對象的數量,然后也可以像使用new, delete那樣的方式來管理內存,不同在于這一段內存空間的管理使用者要調用內存池提供的相應函數(CreateObj, DestoryObj)來操作,而且堆內存由CObjectPool來管理。這樣可以獲得高效率的內存操作。
  為什么這樣子就可以高效率呢?恐怕你有點質疑,人家平常都用new, delete也挺爽的。好了,還是看下面內存池的設計思路吧!
  一、我們為了適應不同的類對象,我們使用了模板的接口類----CObjectPool
      二、MemPool類,內存池的核心類。負責內存管理, 主要使用的數據結構是鏈表結構, 結構為: Object|index, Object是某一類對象的數據, 而index是它在內存中的索引號, 這個很有用, 它是用來維持[已分配列表] 和 [空閑列表] 的地址計算。注:(它是浪費了4個字節的空間,但它的功勞大于它的罪過,你說用不用呢?)

    接下來應該貼代碼了吧,大家都關注這個實質性的東西了!
//============================================================================// FileName  :ObjectPool.h
// CreateDate:2008-02-20
// Author    :chenguihong
// Des       :內存池
//-------------------------------------------------------------------------------------

#ifndef __OBJECT_POOL_H__
#define __OBJECT_POOL_H__

#include "MemPool.h"

template <class T>
class CObjectPool
{   
public:
    CObjectPool(int ObjectReserve = 1000):m_MemPool(sizeof(T),ObjectReserve){}
   
 ~CObjectPool()
 {
  m_MemPool.Release();
 }

    T* CreateObj()
 {
  return static_cast<T*>(m_MemPool.Alloc());
 }
   
 void DestoryObj(void*p)
 {
  m_MemPool.DeAlloc(p);
 }

 int Release()
 {
  return m_MemPool.Release(); 
 }

public:
 MemPool m_MemPool;
};

#endif


//-----------------------------------------------------------------------
//======================================================================
// FileName  :MemPool.h
// CreateDate:2008-02-20
// Author    :chenguihong
// Des       :線程安全的內存池
//-------------------------------------------------------------------------------------
#ifndef   __MEM_POOL_H__
#define   __MEM_POOL_H__

#include <windows.h>
#include "Mutex.h"

class MemPool
{
   

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//一塊內存.內存塊的固定大小為 blockSize * blocks.

//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
public:
    MemPool(size_t block_size, size_t block_reserved);
    bool Init(size_t block_size, size_t block_reserved);
    int Release();

    //----------------------------------------------------
    //查看還有多少空間可以用
    //----------------------------------------------------
    size_t Capacity();

    //----------------------------------------------------
    //分配一個內存和釋放一個內存
    //----------------------------------------------------
    void* Alloc();
    void  DeAlloc(void* p);

    //----------------------------------------------------
    //判斷一個指針是不是由這個Pool分配的。
    //----------------------------------------------------
    bool  Is_ptr(void* p);

private:
    size_t      m_blockSize;       //每一個塊的大小,即FixedAlloctor能分配的大小. 當

m_blockSize不能為1.
    size_t      m_blocks;           //每個MemChunck中,Block的個數.
    size_t      m_avaliableBlocks; // 內存池中,空閑的塊的個數

    //內存塊的地址
    unsigned char* m_pData;
    //第一個可用塊,一個可用塊的大小是由blockSize指定的.
    unsigned long m_firstAvailableBlock;
    unsigned long m_blocksAvailable; //是不是可用的空閑塊
 
 CMutex m_Mutex;
};

#endif


//---------------------------------------------------------------------------------------

/*
MemPool.cpp
*/

#include "MemPool.h"
#include <cassert>
#include <tchar.h>

#include <iostream>
using namespace std;

/********************************************************
內存池分配器.也就是一個固定大小的內存分配器.
Object|index 結構
*********************************************************/

MemPool::MemPool(size_t block_size, size_t block_reserved)
{
 m_pData = NULL;
 m_avaliableBlocks = 0;

    Init(block_size,block_reserved);
}

bool MemPool::Init(size_t blockSize, size_t blocks)
{
    assert(blockSize > 0);
    assert(blocks > 0 && blocks < 10000000); //暫定10000000個,應該足夠了吧!

    m_pData = (unsigned char*) malloc((blockSize + sizeof(unsigned long)) * blocks);

 if(m_pData == NULL)
        return false;

    m_firstAvailableBlock = 0;
 m_blocks = blocks;
    m_blocksAvailable = blocks;
 m_blockSize = blockSize;

 
    //填充內存塊的鏈
    unsigned long i = 0;
    unsigned char* p = m_pData;
 unsigned long* pNext = NULL;

 for (; i != blocks; p += (blockSize + sizeof(unsigned long)))
    {
        pNext = (unsigned long*) (p + blockSize); //200000個整型溢出啊,加大馬力
  *pNext = ++i;
    }

 return true;
}

int MemPool::Release()
{
 //請確保調用者釋放指針方能執行操作
 if(m_blocksAvailable < m_blocks)  //出錯說明有內存申請了但還沒有被釋放
 {
  int Result = m_blocks - m_blocksAvailable;
  return Result; 
 }
 
 if(m_pData != NULL)
 {
  free((unsigned char*)m_pData);
  m_pData = NULL;
  return 0;
 }
}

 

void* MemPool::Alloc()
{
 //多線程訪問要加鎖, 也可以用守衛來自動完成(線程安全)
 Mutex_Guard sc(&m_Mutex);
 unsigned char* pResult = NULL;

 if(m_blocksAvailable > 0)
 {
  //把第一個可用返回給用戶
  //cout<<"申請到第"<<m_firstAvailableBlock+1<<"塊"<<endl;
  pResult = m_pData + (m_firstAvailableBlock * (m_blockSize + sizeof(unsigned

long)));
  m_firstAvailableBlock = *(unsigned long*)(pResult + m_blockSize);
  memset(pResult, 0, m_blockSize); //清0
  m_blocksAvailable--;
 }
 else
 {
  return pResult;
 }
  
   
 return pResult;
}

void  MemPool::DeAlloc(void* p)
{
 //多線程訪問要加鎖, 用守衛來自動完成(線程安全)
 Mutex_Guard sc(&m_Mutex);

 assert(Is_ptr(p)); //檢查是不是非法指針

 unsigned char* toRelease = static_cast<unsigned char*>(p);

 //把釋放掉的塊加入到表頭里.新建一個表頭,表頭下一個塊指向原來的第一個可用塊
 * ((unsigned long*)(toRelease + m_blockSize)) = m_firstAvailableBlock;
 //第一個可用塊指向表頭
 m_firstAvailableBlock = (toRelease - m_pData) / (m_blockSize + sizeof(unsigned

long));
 //塊對齊檢查
 assert(m_firstAvailableBlock == (toRelease - m_pData) / (m_blockSize + sizeof

(unsigned long)));

 m_blocksAvailable++;

 //cout<<"釋放掉第"<<m_firstAvailableBlock+1<<"塊"<<endl;
}


bool MemPool::Is_ptr(void* p)
{
 //內存不在這個里面。也不是他分配的。
    if(p < m_pData  || p > (m_pData + (m_blockSize + sizeof(unsigned long)) * (m_blocks-1)))
  return false;

    //指針沒在blockSize邊界上對齊.肯定不是由這個MemPool分配的
    long result = ((unsigned char*)p - m_pData) % (m_blockSize + sizeof(unsigned long));
 if(result != 0)
  return false;
   
 return true;
}

//----------------------------------------------------
//查看還有多少空間可以用
//----------------------------------------------------
size_t MemPool::Capacity()
{
    return m_blocksAvailable;
}

使用方法:  CObjectPool<int> m_ObjectPool(10000); //10000個對象
                   int *p =  m_ObjectPool.CreateObj();  //相當于new
                   m_ObjectPool.DestoryObj(p);            //相當于delete

好了,代碼到些結束,該出測試報告了吧!

性能測試, 當當當當.....

與普通的系統函數new和delete作對比, 各自開10條線程進行內存申請1,000,000對象, 每條線程反復地進

行申請和釋放。

在CPU:Pentium D 3.0G, 內存1G的情況下:
結果: (1) 采用內存池用時:        5328ms
      (2) 采用new 和 delete用時:27078ms

如果程序中有什么BUG或有什么看法的話,歡迎留言/評論,謝謝!

 

posted on 2008-04-16 09:01 RedLight 閱讀(1983) 評論(3)  編輯 收藏 引用 所屬分類: 網絡服務器開發

評論

# re: 內存池設計[未登錄] 2008-11-18 04:35 張帥

設計的挺好的,學到了,謝謝  回復  更多評論   

# re: 內存池設計 2012-10-13 02:08 Alven

你這個只支持按堆的順序DeAlloc吧....用多線程可以么?  回復  更多評論   

# re: 內存池設計[未登錄] 2014-04-02 08:52 路人甲

你這遠遠不到內存池的概念吧!  回復  更多評論   

<2009年5月>
262728293012
3456789
10111213141516
17181920212223
24252627282930
31123456

導航

統計

公告


Name: Galen
QQ: 88104725

常用鏈接

留言簿(3)

隨筆分類

隨筆檔案

相冊

My Friend

搜索

最新評論

閱讀排行榜

評論排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲免费电影在线观看| 日韩视频在线一区二区三区| 欧美插天视频在线播放| 亚洲视频精品| 欧美国产精品劲爆| 一本色道久久88综合日韩精品| 国产精品剧情在线亚洲| 99精品99| 蜜乳av另类精品一区二区| 一区二区亚洲欧洲国产日韩| 亚洲日韩欧美视频一区| 日韩视频中文字幕| 国产综合久久久久久鬼色| 免费影视亚洲| 欧美aa在线视频| 性欧美暴力猛交69hd| 91久久在线| 极品尤物av久久免费看| 国产精品久久久久毛片大屁完整版| 美女精品一区| 久久av老司机精品网站导航| 日韩亚洲欧美在线观看| 亚洲国产成人av| 欧美.日韩.国产.一区.二区| 香蕉久久久久久久av网站| 日韩一二三在线视频播| 亚洲国产欧美一区二区三区久久 | 亚洲第一精品夜夜躁人人躁| 国产精品国产三级国产aⅴ浪潮| 欧美激情久久久| 欧美xart系列高清| 久久久www成人免费毛片麻豆| 9久草视频在线视频精品| 亚洲人成在线观看网站高清| 亚洲一区二区三区激情| 国产精品美女主播| 国产精品一区二区久久国产| 国产欧美一区在线| 国产一区二区三区的电影| 国产精品私人影院| 国产麻豆日韩欧美久久| 国产专区精品视频| 亚洲成人自拍视频| 亚洲国产三级网| 亚洲精品欧美日韩专区| 99国产麻豆精品| 日韩一级黄色大片| 亚洲免费视频在线观看| 久久久久一区二区| 久久色在线观看| 欧美 日韩 国产在线| 欧美日韩国产欧| 国产精品一区二区三区四区 | 99视频超级精品| 亚洲乱码日产精品bd| 久久色中文字幕| 久久久久国产精品一区三寸| 亚洲国产精品成人精品| 亚洲最新在线| 在线亚洲伦理| 欧美亚洲免费高清在线观看| 久久精品国产精品亚洲综合| 你懂的网址国产 欧美| 欧美黄色大片网站| 亚洲图片欧洲图片av| 久久国产精品色婷婷| 欧美精品乱码久久久久久按摩| 亚洲视频欧美在线| 美女露胸一区二区三区| 亚洲毛片在线免费观看| 久久精选视频| 日韩一级裸体免费视频| 久久久久一本一区二区青青蜜月| 欧美日一区二区在线观看 | 欧美一区二区三区在线播放| 麻豆国产精品777777在线| 一本色道久久综合精品竹菊| 久久成人精品视频| 日韩一区二区福利| 久久综合狠狠综合久久综合88| 欧美日韩国产精品成人| 国模套图日韩精品一区二区| 中文av字幕一区| 欧美 日韩 国产 一区| 亚洲欧美日韩精品久久亚洲区| 亚洲一区二区免费视频| 每日更新成人在线视频| 国内综合精品午夜久久资源| 亚洲综合日本| 亚洲国产欧美另类丝袜| 欧美一区免费| 国产欧美日韩在线| 亚洲在线播放电影| 亚洲三级影院| 亚洲高清免费| 国产毛片精品国产一区二区三区| 精品动漫一区| 久久久久国产精品厨房| 亚洲精品欧洲精品| 欧美不卡在线视频| 亚洲国产成人久久| 老司机精品视频一区二区三区| 一本综合久久| 欧美日韩一区二区三区在线视频| 在线电影一区| 久色成人在线| 久久久国产精彩视频美女艺术照福利 | 国产精品日本精品| 夜夜嗨av一区二区三区网站四季av | 最新亚洲激情| 欧美成人午夜影院| 亚洲黄一区二区三区| 欧美中文字幕久久| 翔田千里一区二区| 国产一区二区主播在线| 亚洲激情中文1区| 欧美激情精品久久久久久免费印度| 免费在线视频一区| 一本一道久久综合狠狠老精东影业 | 欧美日韩一区二区三区| 亚洲国产综合在线看不卡| 在线色欧美三级视频| 欧美成人日韩| 亚洲人成高清| 欧美一区二区免费观在线| 久久久不卡网国产精品一区| 亚洲第一页中文字幕| 欧美国产1区2区| 欧美日韩成人一区二区| 亚洲欧美日韩在线一区| 亚洲欧美一区二区激情| 国产一区二区三区在线观看精品 | 国产免费成人| 你懂的一区二区| 久久国产精品免费一区| 精品动漫3d一区二区三区免费| 久久久久一区二区| 欧美福利视频| 亚洲国产日韩欧美一区二区三区| 永久免费毛片在线播放不卡| 久久av二区| 美女国内精品自产拍在线播放| 国产尤物精品| 久久久久久久综合色一本| 欧美伊人久久久久久久久影院 | 久久久999精品免费| 久久狠狠久久综合桃花| 国产欧美精品一区aⅴ影院| 亚洲午夜激情网页| 香蕉成人伊视频在线观看 | 亚洲精品乱码视频| 久久一区二区三区超碰国产精品| 久久免费精品日本久久中文字幕| 国产日韩精品在线播放| 欧美中文在线免费| 欧美成人激情视频| 亚洲三级免费| 欧美日韩理论| 亚洲欧美综合精品久久成人| 欧美一区二区成人6969| 韩日精品视频一区| 免费久久99精品国产自| 最新中文字幕亚洲| 性欧美xxxx大乳国产app| 国产综合色产| 欧美成人官网二区| 在线亚洲电影| 乱人伦精品视频在线观看| 最新日韩在线视频| 欧美日韩在线播| 欧美一区二区三区在| 久久久久一区二区三区| 最近看过的日韩成人| 国产精品国产三级国产专播品爱网| 亚洲综合日韩在线| 欧美激情综合色| 亚洲专区一二三| 在线欧美日韩| 国产精品久久久久久影视| 久久久在线视频| 夜夜嗨一区二区| 麻豆精品视频在线| 亚洲欧美国产高清va在线播| 一区久久精品| 国产精品日韩久久久| 免费在线观看日韩欧美| 西西裸体人体做爰大胆久久久| 亚洲国产99| 久久综合久色欧美综合狠狠| 夜夜爽夜夜爽精品视频| 国产自产2019最新不卡| 欧美视频一区在线| 欧美大片免费观看| 久久精品首页| 亚洲综合日韩中文字幕v在线| 亚洲人成亚洲人成在线观看| 美女图片一区二区| 久久精品噜噜噜成人av农村| 中文在线一区| 91久久久一线二线三线品牌|