征求频繁new/delete提升速度的解决办法

------
背景:
每隔200ms左右就会new一个50KB左右的内存空间,然后在间隔很短的时间内又释放。现在需要一个内存池配合现有的代码,希望能改善目前频率很高的new和delete操作。

boost的pool怎样?看介绍是适合小内存的快速申请。

大家推荐个内存池实现吧,最好有线程安全的
------
为什么要delete掉呢,你可以把内存保留起来,将其至零,当下一个需要分配内存时候,直接将这个储存的内存分给它
------
我想得到一个可重用得内存池
------
《Memory Pool的设计哲学和无痛运用》推荐你看这个
------
其实我觉得CMemFile你也可以自己好好封装下,当内存池用
------
我觉得没必要频繁的new、delete
使用像3楼所说的方法,使用一个链表来管理内存。
这样效率也高些
------
就是没必要,所以就想用内存池

我申请的内存大小每次都不一样,有时相差10KB左右,有时差1KB左右,这个差距是很大的
所以这里有点棘手
------

引用 7 楼 chenyu2202863 的回复:
就是没必要,所以就想用内存池

我申请的内存大小每次都不一样,有时相差10KB左右,有时差1KB左右,这个差距是很大的
所以这里有点棘手

------
设计下算法不就好了嘛
------
http://topic.csdn.net/t/20040908/13/3351823.html
------
哎,懒人不好做,自己实现去了!
------
200ms不算是高频次吧,
按LZ的意思应该是在下一个分配之前已经释放了,那么也就是始终最多只有一个缓冲池,那就可以用一个指针和一个记录缓冲区大小的变量,仅在需要的缓冲区大于当前已分配的缓冲区时才进行新的分配(销毁原先的,分配新的),这样就用一个满足最大数据量要求的缓冲区来做当期缓冲区,分配的频次可以大大降低,
自然不使用动态的是频次最低的
------
确定最大同时需要多少个内存块,假如是N块。程序启动时直接申请N*600K大小的内存。用一个数组记录哪个内存块在使用,哪个空闲。
这样当有需要的时候,直接使用空闲块即可。
或者定义一个N大小的指针数组M,需要使用时申请一块内存,然后设置M中的一个元素指向它。不使用时,只做一下标记,不真的释放。
只有当程序退出时才释放。
------
楼上:
我的需求是不确定有多少内存需要申请,而且每次申请的大小不一样。
绝对不能使用静态的空间
------
重载new和delete操作符,实现一个简单的内存管理器就可以了,删除内存时不真的删除,仅仅做一个标记,申请内存时从缓存列表里寻找已有的、标记为删除的、大小刚刚比目标大一点的内存块,找到就返回并标记为正在使用,找不到才真正分配内存。

你还可以对这个管理器进行优化,例如按照使用需求把内存大小分成若干个等级,每个等级预先分配一些内存备用;为每个内存块添加引用计数和时间戳,长期不用的内存可以释放掉,或者方便自己统计分析;提供自动回收机制;甚至可以完全不用释放函数(跟java的垃圾回收一样)而不会导致内存泄露。

自己设计内存管理器可简可繁,完全按照需求设计。
------
正如楼上所言,现在我就在做这件事!

“你还可以对这个管理器进行优化,例如按照使用需求把内存大小分成若干个等级,每个等级预先分配一些内存备用”--这个何解?可以在详细点吗?
------
Windows早就为你想好了,使用这些函数
 HeapAlloc, HeapDestroy, HeapFree, HeapReAlloc, HeapSize, HeapValidate, HeapCreate
就可以了,其实new和delete最终也是在调用Windows的VirtualAlloc和VirtualFree函数,这问题应从Windows内存管理方面找方法,能使用API的应少使用c/c++的函数
------
把分配的内存按整型对齐分配,这样系统操作快,切不产生碎片
------
推荐看下STL、的小内存管理。比较适合你
------
引用 15 楼 jameshooo 的回复:
重载new和delete操作符,实现一个简单的内存管理器就可以了,删除内存时不真的删除,仅仅做一个标记,申请内存时从缓存列表里寻找已有的、标记为删除的、大小刚刚比目标大一点的内存块,找到就返回并标记为正在使用,找不到才真正分配内存。

你还可以对这个管理器进行优化,例如按照使用需求把内存大小分成若干个等级,每个等级预先分配一些内存备用;为每个内存块添加引用计数和时间戳,长期不用的内存可以释放掉,或者方便自己统计分析;提供自动回收机制;甚至可以完全不用释放函数(跟java的垃圾回收一样)而不会导致内存泄露。

自己设计内存管理器可简可繁,完全按照需求设计。

------
帮顶!
------
学习了,全是大牛
------
学习了!都是为了不频繁删除内存!找适合自己的方法是最好的!上面好几位大牛提的建议不错,楼主综合考虑吧!
------
频繁new/delete,对于客户端程序,可以忽略,对于服务器类程序,需要花点儿时间写几行代码
通常就是采用jameshooo(浆糊)的做法:

在程序启动时建立一个合适大小的缓存区结构数组(根据负载和硬件配置决定)
写一个同步函数(比如:GetMyStruct),通过该函数获取空闲的缓存区结构,用完后置Idle
如果所需缓存区空间超过了标配,就回到老路(new/delete)
 
------
此贴值得关注下 UP 学习了 谢谢
------
引用 12 楼 zgl7903 的回复:
200ms不算是高频次吧,
按LZ的意思应该是在下一个分配之前已经释放了,那么也就是始终最多只有一个缓冲池,那就可以用一个指针和一个记录缓冲区大小的变量,仅在需要的缓冲区大于当前已分配的缓冲区时才进行新的分配(销毁原先的,分配新的),这样就用一个满足最大数据量要求的缓冲区来做当期缓冲区,分配的频次可以大大降低,
自然不使用动态的是频次最低的

------
引用 14 楼 chenyu2202863 的回复:
楼上:
我的需求是不确定有多少内存需要申请,而且每次申请的大小不一样。
绝对不能使用静态的空间

------
每个内存块标配1M(通常需要500k的话),配置50块,才50M,对于现在内存价格,就几块钱,算不了什么:)
计算机内存,无须精确分配,就像房子,大点舒服,减少无意中撞墙的次数:)
------
50K左右的内存,这个左可以是几K,右可以上MB,相差太大@
------
没有关系的,考虑99.9%的需求
比如,一个文章系统,文章可能最少1个字(2字节),最多10几M,但是99.9%不会超过2M,就按2M配置
不要太在意几M内存的闲置,以空间换时间,就必须拿出空间成本
------
引用 14 楼 chenyu2202863 的回复:
楼上:
我的需求是不确定有多少内存需要申请,而且每次申请的大小不一样。
绝对不能使用静态的空间

------
关注 学习
------
三楼的方法很好,学习~
------
引用 15 楼 jameshooo 的回复:
重载new和delete操作符,实现一个简单的内存管理器就可以了,删除内存时不真的删除,仅仅做一个标记,申请内存时从缓存列表里寻找已有的、标记为删除的、大小刚刚比目标大一点的内存块,找到就返回并标记为正在使用,找不到才真正分配内存。

你还可以对这个管理器进行优化,例如按照使用需求把内存大小分成若干个等级,每个等级预先分配一些内存备用;为每个内存块添加引用计数和时间戳,长期不用的内存可以释放掉,或者方便自己统计分析;提供自动回收机制;甚至可以完全不用释放函数(跟java的垃圾回收一样)而不会导致内存泄露。

自己设计内存管理器可简可繁,完全按照需求设计。

------
听你的说明,估计你不是需要池,而是需要一个buff。
------
哈哈 ,我自己也做了个,吃晚饭我测试下速度,如果可行我也放出源码,希望大家指点下
------
看不懂,真麻烦!
------
测试结果:

1.在XP sp3的笔记本上用vs2008编译的程序执行测试代码
 结果: 使用new/delete的速度是Memor Pool的一倍

2.在XP sp2的台式机上用vc6编译的程序执行测试代码
 结果: 使用Memory的速度是Poolnew/delete的一倍
------
是必要的函数inline,然后用Release优化后。
哈哈,效果比普通的好上几倍了!!
------
对于内存管理器的设计,可以给你提供几条设计准则:

1、需要长期保持运行的机器才可能需要一个合适的内存管理器。例如服务器可能需要,但客户端通常不需要。

2、对内存、性能都有严格要求的程序才需要内存管理器,例如支持海量用户的服务器。

3、在内存和性能的平衡上,使用2-8原则通常能发挥最大的效能。你可能会在很多方面进行优化,内存管理器只是一个方面,而优化只需要针对80%的情况即可。举个例子,假设你需要预分配某些大小的内存,而这些内存大小是在10K-100K,在统计学的基础上,你发现40K-70K的内存申请的概率是80%,那么你的优化方案只处理40K-70K这个内存区间即可,把概率小的部分排除在外,即概率大的使用优化方案,概率小的使用原始方案,整体性能已经大大提高了。如果全面优化,效果可能适得其反,甚至为了优化剩下的20%而需要花费80%的时间和精力(这是2-8原则的另一种用途……只花费20%的力量却可以解决80%的问题)。

4、减少耦合性,增强可配置性。内存无非就是申请、释放、重分配,那么内存管理器也应该遵循这些操作模式,以后替换或者取消内存管理器就非常方便了。定义好管理器的要素,在不同物理环境下可以使用不同的配置,例如总物理内存、预分配内存(或比例)、CPU个数、某些门限值等等,这些可配置的要素是通过经验和验证计算出来的。
------
设计下算法不就好了嘛
------
学习了
------
自己写个内存池不就行了?
------
还是自己实现简单
------
貌似这个系统已经帮你设计好了的。你释放的时候并不是真正的还给系统

书上说的
------
ding
------
ai
------
有用吗
------
赚点分赚点分赚点分
------
赚点分赚点分赚点分
------
45 楼 学习了
------
楼主厉害,强贴要留名。
------
好贴,收藏学习。
------
不行了,这个一定要收藏。
------
每天回帖即可获得10分可用分!小技巧:教您如何更快获得可用分
------
学习

------
一般就用boost的么~
------
學習了。。都太厲害了!
------
我觉得new delete这样的一些操作,是非常多的专家经过深思熟虑写出来的
在速度上和其它方面都有非常多的考虚。

为什么程序员都想把非常多的东西自己拿来写呢?呵呵,我有时候也爱这样。

不过,我现在不了
我做过软件时测试自己程序的容量,树形内存,最大分支有几万个点,然后进行删除操作
发现速度非常慢,我也常试标注一下,不删除,可带来其它问题。
我仔细检查程序后,把一些不必要的if删除然后再测,没想到同样的数据再删除时几乎不需要时间了...

程序结构流程的优化,才是提升速度的根本

不知我说的对否。


------
呵呵,WIN7内存管理比XP优化多了,直接用new/delete可能更快。往往当你处理链表的时间复杂度大于new的时间时候,还不如直接new。
------
学习啦
------
Study
------
内存池,好像比较高深,学习学习!
------
学习
------
请参照memcached的内存设计
有若干的slab,每个slab为一个内存等级,分配了若干相同大小的block链表连接起来。
查找内存,先计算所需内存的大小,再到相应的slab取的内存block
释放的时候不删除

当然你可以复用它的代码



------
用TBB不就行了。
------

实现了变长内存池的申请和回收,其中回收包括在某种特定的情况下回收给系统

 

h文件:GenMemPool.h 

#ifndef _SKIFFER_GENMEMPOOL_H
#define _SKIFFER_GENMEMPOOL_H

#include <stdlib.h>

//按此值向上取整申请所需内存大小,例如,如果申请内存为13字节,则返回14字节的内存
#define MEMPOOL_ALIGNMENT (2)
#define MAX_MEN_LIMIT (1<<16)
#pragma pack(1)
struct STMemBlk
{
//此内存块中内存单元的个数
unsigned short m_wAllUnitNum;
//空闲单元的个数
unsigned short m_wFreeUnitNum;
//第一个空闲单元的单元编号
unsigned short m_wFirstFreeUnitNo;
//next 指针
STMemBlk *m_pNextBlk;
//以上为内存块结构头部信息

//以下为外界可用内存
char m_pData[0];

STMemBlk()
{
  m_wAllUnitNum = 0;
  m_wFreeUnitNum = 0;
  m_wFirstFreeUnitNo = 0;
  m_pNextBlk = NULL;
}
~STMemBlk()
{
}

void* operator new(size_t wBlkSize, unsigned short wUnitNum, unsigned short wUnitSize)
{
  return ::operator new (sizeof(STMemBlk) + wUnitNum * wUnitSize);
}

void operator delete(void *p)
{
  ::operator delete (p);
}

void operator delete(void *p, unsigned short wUnitNum, unsigned short wUnitSize)
{
  ::operator delete (p);
}
};

struct STInitParam
{
//每个内存单元的大小
unsigned short m_wUnitSize;
//第一次初始化时,每一块内存中,需要申请的内存单元个数
unsigned short m_wInitUnitNum;
//内存不足时,每一块内存中,需要申请的内存单元个数
unsigned short m_wGrowUnitNum;
STInitParam()
{
  m_wUnitSize = 0;
  m_wInitUnitNum = 0;
  m_wGrowUnitNum = 0;
}
};
#pragma pack()


class CMemPool
{

public: 
CMemPool();
~CMemPool();

//初始化 
void Init(unsigned short wUnitSize, unsigned short wInitUnitNum, unsigned short wGrowUnitNum);
//分配内存块中的一个内存单元
void* Alloc();
//释放一个内存单元
void Free(void *pUnit);
//预处理块
void* PreAlloc(STMemBlk *pstMemBlk, int dwBlkFlag);

private:
//内存池头结点
STMemBlk *m_pstMemBlkHead;
//内存池块信息
STInitParam m_stInitBlkInfo;
};

class CVarLenMemPool
{
public:
CVarLenMemPool();
~CVarLenMemPool();

//申请dwMemSize字节的内存
void* Alloc(unsigned int dwMemSize);
//释放内存
void Free(void *p);
//初始化n个内存单元长度不同的固定内存池 
void Init(const STInitParam *pstInitParam, unsigned short wMemPoolNum);
//退出
void Exit();
//向上对齐
void UpAlignment(STInitParam *pstInitParam, unsigned short wMemPoolNum);

public:
//内存单元大小不同的内存池
CMemPool **m_ppMemPoolList;
//n个内存单元长度不同的固定内存池 
STInitParam *m_pstInitParam; 
//内存池个数
unsigned short m_wMemPoolNum;
//最大的内存单元大小
unsigned short m_wMaxUnitSize;
};

#endif




.cpp文件:GenMemPool.cpp

#include "GenMemPool.h"
#include <string.h>

CMemPool::CMemPool()
{
m_pstMemBlkHead = NULL;
memset(&m_stInitBlkInfo, 0 , sizeof(m_stInitBlkInfo));
}

CMemPool::~CMemPool()
{
}

void CMemPool::Init(unsigned short wUnitSize, unsigned short wInitUnitNum, unsigned short wGrowUnitNum)
{
if(wUnitSize <= 4)
{
  wUnitSize = 4;
}
else
{
  wUnitSize = (wUnitSize + (MEMPOOL_ALIGNMENT - 1)) & ~(MEMPOOL_ALIGNMENT - 1);
}
m_stInitBlkInfo.m_wUnitSize = wUnitSize;
m_stInitBlkInfo.m_wInitUnitNum = wInitUnitNum;
m_stInitBlkInfo.m_wGrowUnitNum = wGrowUnitNum;
}

void* CMemPool::PreAlloc(STMemBlk *pstMemBlk, int dwBlkFlag)
{
char *pData = NULL;
unsigned short dwUnitNum = 0;
pData = pstMemBlk->m_pData;

if(dwBlkFlag == 1)
{
  dwUnitNum = m_stInitBlkInfo.m_wInitUnitNum;
}
else
{
  dwUnitNum = m_stInitBlkInfo.m_wGrowUnitNum;
}

pstMemBlk->m_wFreeUnitNum = dwUnitNum - 1;
pstMemBlk->m_wAllUnitNum = dwUnitNum;
pstMemBlk->m_wFirstFreeUnitNo = 1;

for(unsigned short dwUnit = 1; dwUnit < dwUnitNum - 1; ++dwUnit)
{  
  pData = pstMemBlk->m_pData + dwUnit * m_stInitBlkInfo.m_wUnitSize;
  *(unsigned short*)pData = dwUnit + 1;
}
pData = pstMemBlk->m_pData;
return pData;
}

void* CMemPool::Alloc()
{
void *pData = NULL;
STMemBlk *pstMemBlk = NULL;

if(m_pstMemBlkHead == NULL)
{
  m_pstMemBlkHead = ::new STMemBlk;
  m_pstMemBlkHead->m_pNextBlk = new(m_stInitBlkInfo.m_wInitUnitNum, m_stInitBlkInfo.m_wUnitSize)STMemBlk;
  pData = PreAlloc(m_pstMemBlkHead->m_pNextBlk, 1);
}
else
{
  pstMemBlk = m_pstMemBlkHead->m_pNextBlk;
  while(pstMemBlk != NULL)
  {
  if(pstMemBlk->m_wFreeUnitNum == 0)
  {
  pstMemBlk = pstMemBlk->m_pNextBlk;
  continue;
  }
  else
  {
  break;
  }
  }
  if(NULL == pstMemBlk)
  {
  pstMemBlk = new(m_stInitBlkInfo.m_wGrowUnitNum, m_stInitBlkInfo.m_wUnitSize)STMemBlk;
  pData = PreAlloc(pstMemBlk, 2);
  pstMemBlk->m_pNextBlk = m_pstMemBlkHead->m_pNextBlk;
  m_pstMemBlkHead->m_pNextBlk = pstMemBlk;
  }
  else
  {
  pData = (void*)(pstMemBlk->m_pData + pstMemBlk->m_wFirstFreeUnitNo * m_stInitBlkInfo.m_wUnitSize);
  --(pstMemBlk->m_wFreeUnitNum);
  pstMemBlk->m_wFirstFreeUnitNo = *(unsigned short*)pData;
  }
}
return pData;
}

void CMemPool::Free(void *pUnit)
{
STMemBlk *pstMemBlk = NULL;
STMemBlk *pstMemBlkPre = NULL;
unsigned short dwBlkNo = 0;
pstMemBlkPre = m_pstMemBlkHead;
pstMemBlk = m_pstMemBlkHead->m_pNextBlk;

while(pstMemBlk != NULL)
{
  if(((unsigned int)pUnit) > (unsigned int)pstMemBlk && 
  (unsigned int)pUnit < 
  (unsigned int)(pstMemBlk->m_pData + (pstMemBlk->m_wAllUnitNum + 1) * m_stInitBlkInfo.m_wUnitSize))
  {
  dwBlkNo = ((unsigned int)pUnit - (unsigned int)(pstMemBlk->m_pData))/m_stInitBlkInfo.m_wUnitSize;
  break;
  }
  else
  {
  pstMemBlkPre = pstMemBlk;
  pstMemBlk = pstMemBlk->m_pNextBlk;
  }
}

if(pstMemBlk->m_wFreeUnitNum - 1 == pstMemBlk->m_wAllUnitNum)
{
  pstMemBlkPre->m_pNextBlk = pstMemBlk->m_pNextBlk; 
  delete(pstMemBlk);
}
else
{
  *(unsigned short*)pUnit = pstMemBlk->m_wFirstFreeUnitNo;
  pstMemBlk->m_wFirstFreeUnitNo = dwBlkNo;
  ++(pstMemBlk->m_wFreeUnitNum);
}
}


CVarLenMemPool::CVarLenMemPool()
{
m_ppMemPoolList = NULL;
m_pstInitParam = NULL;
m_wMemPoolNum = 0;
m_wMaxUnitSize = 0;
}

CVarLenMemPool::~CVarLenMemPool()
{
}

void CVarLenMemPool::Init(const STInitParam *pstInitParam, unsigned short wMemPoolNum)
{
unsigned short wInitIdxBegin = 0; 
unsigned short wInitIdxEnd = 0;
m_wMemPoolNum = wMemPoolNum;
m_pstInitParam = new STInitParam[m_wMemPoolNum];
memcpy(m_pstInitParam, pstInitParam, sizeof(*pstInitParam) * wMemPoolNum);
UpAlignment(m_pstInitParam, wMemPoolNum);

m_wMaxUnitSize = 0; 
unsigned short i = 0;

for(i = 0; i < m_wMemPoolNum; ++i)
{
  if(m_pstInitParam[i].m_wUnitSize > m_wMaxUnitSize)
  {
  m_wMaxUnitSize = m_pstInitParam[i].m_wUnitSize;
  }
}

m_ppMemPoolList = new CMemPool*[m_wMaxUnitSize+1];

for(i = 0; i < m_wMemPoolNum; ++i)
{
  CMemPool *pMemPool = new CMemPool;
  pMemPool->Init(m_pstInitParam[i].m_wUnitSize, m_pstInitParam[i].m_wInitUnitNum, 
  m_pstInitParam[i].m_wGrowUnitNum);
  wInitIdxEnd = m_pstInitParam[i].m_wUnitSize;

  for(unsigned short j = wInitIdxBegin; j <= wInitIdxEnd; ++j)
  {
  m_ppMemPoolList[j] = pMemPool;
  }
  wInitIdxBegin = wInitIdxEnd + 1;
}
}

void* CVarLenMemPool::Alloc(unsigned int dwMemSize)
{
void *p = NULL;
if(dwMemSize+2 > m_wMaxUnitSize)
{
  p = ::operator new(dwMemSize+2);
  *(unsigned short*)p = 0;
}
else
{
  p = m_ppMemPoolList[dwMemSize+2]->Alloc();
  *(unsigned short*)p = dwMemSize+2;
}
return ((unsigned short*)p+1);
}

void CVarLenMemPool::Free(void *p)
{
unsigned short *pTmp = ((unsigned short*)p)-1;
unsigned short dwSize = *pTmp;
if(0 == dwSize)
{
  ::operator delete(pTmp);
}
else
{
  m_ppMemPoolList[dwSize]->Free(p);
}
}

void CVarLenMemPool::UpAlignment(STInitParam *pstInitParam, unsigned short wMemPoolNum)
{
for(unsigned short wParam; wParam < wMemPoolNum; ++wParam)
{
  if(pstInitParam[wParam].m_wUnitSize <= 4)
  {
  pstInitParam[wParam].m_wUnitSize = 4; 
  }
  else
  {
  pstInitParam[wParam].m_wUnitSize = (pstInitParam[wParam].m_wUnitSize + (MEMPOOL_ALIGNMENT - 1)) &
  ~(MEMPOOL_ALIGNMENT - 1);  
  }
}
}


void CVarLenMemPool::Exit()
{

}


------
楼主的方法还是不错的,不过每次分配的时候都要检索一次还要排序不慢就奇怪了,应该有更好的方法吧.............如预先把内存分为10类,如1k的,5k的,10k的........1m的等等,然后按照大概的同时使用的几率分配好有多少个,然后每次直接取相应的最小内存就是了,这个是以空间换时间吧.
------
看看 帮顶
------
按楼主的描述,好像只是临时使用,数据长度也大概确定在50K左右
其实应该有个最简单的方法,就是给每个线程各分配一块内存(比如100K),线程启动时申请,过程中随便用,线程结束时释放。

有简单的方法没必要去搞内存池什么的吧
------
顶一下!
------
不懂,看看,了解下!
------
学习
------
你可以看看Google TCMalloc,支持Linux和Windows,可能对你有帮助。
http://goog-perftools.sourceforge.net/doc/tcmalloc.html
http://shiningray.cn/tcmalloc-thread-caching-malloc.html

其他的DLMalloc。
------
帮顶下。
------
顶一下
你的new/del这么快,如果是用一个线程,可以考虑刚开始就申请一块大的内存,每次都用这块就可以了,定义变量每次使用的长度
------
支持 用不同的线程 内存块是不一样的
------
#ifndef _DYNAMIC_H_DKJ1546
#define _DYNAMIC_H_DKJ1546

typedef struct tagNODE
{
int iState;
int iSize;
  tagNODE *pNext;
}T_NODE, *PT_NODE;

class Dynamic
{
private :
T_NODE *pHead;
T_NODE *pTail;

public:
~Dynamic();
T_NODE *Find(int);
T_NODE *Add(int);
void Free(T_NODE *);
};

#endif 


//.cpp

#include <iostream>
using namespace std;
#include "Dynamic.h"

Dynamic::~Dynamic()
{
T_NODE *pCur;
while(pHead != NULL)
{
pCur = pHead;
pHead = pHead->pNext;
delete pCur;
}
}

T_NODE *Dynamic::Add(int iSize)
{
T_NODE * pCur = (T_NODE *) new char[iSize + sizeof(T_NODE)];
pCur->iState = 1;
pCur->iSize = iSize;
pCur->pNext = NULL;
  if(!pHead)//第一块内存
{
pHead = pCur;
pTail = pCur;
return pCur;
}
else
{
pTail->pNext = pCur;
pTail = pCur;
  return pCur;
}
}

T_NODE *Dynamic::Find(int iSize)
{
T_NODE *pCur = pHead;

while (pCur != NULL)
{
if (pCur->iSize >= iSize)//找到合适的内存
{
return pCur;
}
else
{
pCur = pCur->pNext;
}
}

return Add (iSize); //没有找到合适的
}

void Dynamic::Free(T_NODE *pNode)
{
T_NODE *pCur = pHead;
pNode->iState = 0;
while (pCur->pNext != pNode)
{
pCur->pNext;
}
pCur->pNext = pNode->pNext;
pNode->pNext = pHead->pNext;
pHead = pNode;
}

请高手指点一下!
http://shop58830427.taobao.com/
------
ding
------
#define SIZE_100K (1024*100)
#define BUFF_COUNT 10

class MyMemory
{
static void Init()
{
  memset(m_buff, 0, sizeof(m_buff));
  int i = 0;

  for(i=0; i<BUFF_COUNT; i++)
  {
  m_byUse[i] = 0;
  }
}

static BYTE* GetBuffer()
{
BYTE *pBuff = NULL;
int i = 0;
for(i=0; i<BUFF_COUNT; i++)
{
  if(m_byUse[i] == 0)
  {
  pBuff = m_buff+(i*SIZE_100K);
  m_byUse[i] = 1;
  break;
  }
}

return pBuff;
};

static void ReleaseBuffer(BYTE* pBuff)
{
  if(pBuff < m_buff || pBuff > SIZE_100K*(BUFF_COUNT-1) )
  {
  return; 
  }

  DWORD dwPos = (pBuff - m_buff) / SIZE_100K;
  if(dwPos >=0 && dwPos < BUFF_COUNT)
  {
  m_buUse[dwPos] = 0;
  memset(pBuff, 0, SIZE_100K);
  }
};

private:
static BYTE m_buff[SIZE_TOTAL];
static BYTE m_byUse[BUFF_COUNT];
};

------
MARK
------
借鉴下MFC CString的内存管理吧,比较简单也很实用
------
类似的东西写过好几个了,都是工业级应用了

基本上两种方法最有效,一是重载new delete运算符,二是用placement new

------
mark,学习了
------
学习了!谢谢!
------
mark!
------
mark!
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值