定长单元的批次内存缓存池的简洁实现

来源:互联网 发布:闲鱼交易网络课程账号 编辑:程序博客网 时间:2024/06/05 23:54

问题描述:

1.内存管理计算机编程中一个基本问题,其目的在于:

 1)一次可分配多个单元块,缓存维护,以改善反复的小对象申请的性能开销;

2) 管理以分配的内存,有效减少碎片的产生;

3) 保证软件使用的内存透明,了解峰值,了解使用情况,便于优化查错;

2.常用的内存管理机制有以下:

1) 变长块,依靠链表维护,一个节点一块申请了的内存,内存块大小不等,等接到一个申请时,先查维护的链表,若有可从链表取出。这种方法有很多缺点:1,当申请的内存块要遍历链表节点找到大小合适的块,最坏情况下需要把链表所有节点遍历一遍,2.造成浪费,当从链表拿到块的大小远大于所需时,造成浪费;

 2)定长单元,系统维护一个内存链表的数组,数组每项对应一个等长的多个内存单元,一次分配好。当申请到来时, 先根据申请尺寸确定对应的数组项,然后从链表头上返回所需内存节点,归还时可加尾部或者头部;

3.本文按定长单元的思想实现,实现方法由于利用了STL vector数组充当内存维护所需的链表数组,所以程序实现很简洁;

4. 本文内存池接口和系统内存操作接口做了性能上的比较;


程序代码:

#ifndef _MEMORY_BLOCK_CACHE_H_#define _MEMORY_BLOCK_CACHE_H_#include <stdlib.h>#include <vector>#include "windows.h"#define ALIGN( size, bits )  ( ( ( ( size - 1 ) >> bits ) + 1 ) << bits )/** memory pool fixed length block ***/class MemoryBlockCache{public:static const int MAXBLOCK = 256;static const int MALLOCKSIZE = 4096;static const int DEFAULTBASELEN = 4;typedef struct tagMemStatInfo{char*   allocMem;size_t  allocSize;tagMemStatInfo():allocMem(0),allocSize(0){}tagMemStatInfo( char* mem, size_t size ):allocMem(mem),           allocSize(size){}}MemStatInfo, *pMemStatInfo;/****/MemoryBlockCache( size_t baseLen =  DEFAULTBASELEN ):m_pool(0),             m_poolSize(0), m_baseLen(baseLen), m_memStat(){Init( m_baseLen );}/****/~MemoryBlockCache(){Release();}/** Release all memory allocated**/void Release(){std::vector<MemStatInfo>::iterator iter = m_memStat.begin();while( iter != m_memStat.end() ){free( iter->allocMem );++iter;}for( size_t i = 0; i < m_poolSize; i++ ){m_pool[i].clear();}}/** get memory for given length from cahce array or os**/void* Malloc( size_t len ){assert( len > 0 );size_t size = ALIGN( len, 2 );if( size > MAXBLOCK ){return malloc(size);}if( !m_pool[size].size() ){char* buf = (char*)malloc( MALLOCKSIZE );size_t blockNums = MALLOCKSIZE / size;            m_pool[size].reserve( blockNums );for( size_t i = 0; i < blockNums; i++ ){m_pool[size].push_back( buf + i * size );}m_memStat.push_back( MemStatInfo( buf, MALLOCKSIZE ) );}char* res = m_pool[size].back();m_pool[size].pop_back();return res;}/** give back memory to cache or os**/void Free( void* mem, size_t len ){assert( len > 0 );size_t size = ALIGN( len, 2 );if( size > MAXBLOCK ){return free( mem );}m_pool[size].push_back( (char*)mem );}private:/****/void Init( size_t baseLen ){m_poolSize = MAXBLOCK / baseLen;m_pool = new std::vector<char*>[m_poolSize];}private:std::vector<char*>  *m_pool;      // memory block arraysize_t               m_poolSize;  // the size of memory block arraysize_t               m_baseLen;   // std::vector<MemStatInfo> m_memStat;};//test object onetypedef struct tagBlockTestObj{int first;int second;tagBlockTestObj():first(0), second(0){}tagBlockTestObj( int i, int j ):first(i), second(j){}}BlockTestObj, *pBlockTestObj;// test object twotypedef struct tagBlockTestExtObj{int first;int second;std::string  name;tagBlockTestExtObj():first(0), second(0){}tagBlockTestExtObj( int i, int j, const char* str ):first(i), second(j), name( str ){}}BlockTestExtObj, *pBlockTestExtObj;/** Test os memory operation**/void TestOSMemory(){unsigned long start = GetTickCount();const int len = 2000000;int halfLen = len / 2;pBlockTestObj* objs = new pBlockTestObj[len];pBlockTestExtObj* objExts = new pBlockTestExtObj[len];for( int i = 0; i < len; i++ ){objs[i] = new BlockTestObj( i, i );objExts[i] = new BlockTestExtObj( i, i, "test" );delete objs[i];delete objExts[i];}unsigned long interval = GetTickCount() - start;printf(" system call consume time  %d for memory operation \n", interval );delete [] objs;delete [] objExts;}/**Test memory pool ***/void TestMemoryBlock(){unsigned long start = GetTickCount();const int len = 2000000;int halfLen = len / 2;MemoryBlockCache memPool;pBlockTestObj* objs = new pBlockTestObj[len];pBlockTestExtObj* objExts = new pBlockTestExtObj[len];for( int i = 0; i < len; i++ ){void* buf = memPool.Malloc( sizeof(BlockTestObj) );objs[i] = new (buf) BlockTestObj( i, i );buf = memPool.Malloc( sizeof(BlockTestExtObj) );objExts[i] = new (buf) BlockTestExtObj( i, i, "test" );memPool.Free( buf, sizeof(BlockTestObj) );memPool.Free( buf, sizeof(BlockTestExtObj) );}unsigned long interval = GetTickCount() - start;printf(" memory pool call consume time  %d for memory operation \n", interval );delete [] objs;delete [] objExts;}/**Test interface for memory operation***/void TestSuiteMemoryBlock(){TestMemoryBlock();TestOSMemory();}#endif 



compile and run in visual studio 2005

1 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 18个月宝宝咳嗽流鼻涕怎么办 6个月宝宝流鼻涕打喷嚏怎么办 宝宝18个月流鼻涕怎么办 18个月宝宝感冒流鼻涕怎么办 小孩睡觉鼻子不通气怎么办 宝宝鼻子里有鼻涕出不来怎么办 孩子喉咙有痰呼呼响怎么办 六个月宝宝鼻塞怎么办速效办法 两个月小孩鼻子不通气怎么办 一岁宝宝流清鼻涕怎么办 孩子鼻子里有鼻涕怎么办 宝宝晚上睡觉鼻子不通气怎么办 宝宝感冒睡觉鼻子不通气怎么办 宝宝3个月流鼻涕怎么办 小孩吃着了发烧怎么办 半岁宝宝鼻子塞怎么办 宝宝伤风鼻子不通气怎么办 二十天的宝宝伤风鼻子不通怎么办 一个多月的宝宝鼻子有鼻屎怎么办 2个月宝宝鼻子里有鼻屎怎么办 四个月婴儿感冒发烧怎么办 一个月婴儿感冒发烧怎么办 五个月婴儿感冒发烧怎么办 两个月的婴儿感冒发烧怎么办 9个月婴儿感冒发烧怎么办 两个月婴儿感冒鼻塞咳嗽怎么办 两个月婴儿感冒咳嗽流鼻涕怎么办 小孩感冒发烧怎么办速效办法 宝宝打喷嚏流清鼻涕怎么办 宝宝感冒流清鼻涕怎么办 2岁感冒流清鼻涕怎么办 小孩感冒流清鼻涕怎么办 4岁宝宝半夜发烧怎么办 四岁宝宝免疫力低下怎么办 两岁宝宝咳嗽流鼻涕怎么办 小婴儿流清鼻涕怎么办 14个月宝宝流鼻涕怎么办 小孩一直流黄鼻涕怎么办 咳嗽有痰 浓鼻涕怎么办 儿童鼻窦炎总反复流脓鼻涕怎么办? 宝宝感冒咳嗽流黄鼻涕怎么办