MyException - 我的异常网
当前位置:我的异常网» VC/MFC » 同步内存池的实现,该怎么解决

同步内存池的实现,该怎么解决

www.MyException.Cn  网友分享于:2013-03-17  浏览:17次
同步内存池的实现
内存管理一直是C/C++程序员的一块心病,因为它太灵活了,很容易出错,比如常见的内存泄漏,访问地址无效等错误。还有一些是不那么严重的错误,不会是你的程序处于
危险的边缘,确会降低程序的运行效率,这就是——内存碎片。
  所谓内存碎片,就是操作系统的内存管理策略的一种弊端。现代操作系统的内存分配策略大致有一下两种:第一种是固定内存分配,也就是说操作系统将内存分配为固定大小
的内存页,用户需要内存时,操作系统查找第一个符合要求的内存页然后返回,这种策略的好处就是不会造成内存碎片,坏处也显而易见就是内存浪费。第二种策略就是连续内存分配,
操作系统先将内存分配成许多大小不等的连续内存页,用户需要内存时,查找到一个有足够大小的内存页,然后从这个内存页分配用户所需大小的内存返回,这样不会造成内存空间的浪费。
但是由于是在一个连续的内存页中分割一块内存,所以可能会造成分割所剩的内存非常小,以致不满足任何用户的需求,导致内存空间被闲置。在windows操作系统中,就采用了第二种内存分配
策略,在频繁的内存分配和释放过程中,很容易形成内存碎片,而导致系统运行效率低下。
  一般在编程中,解决内存碎片的方法是采用池技术。预先将所需的内存分配好,然后应用程序从这个池中分配内存,用完后释放到这个池中,而不是提交给操作系统来释放内存,这样可以
避免内存的频繁操作,从而解决内存碎片问题。本文将介绍一种采用队列化管理的多线程安全的内存池技术,给出代码并做详细解释。

template <typename Type>  
struct LinkNode 
{  
  Type data; //数据成员,来自于模板定义
  LinkNode<Type> * pNext; //指向下一个节点的指针
};
该结构是内存池队列的结点,采用模板化定义,可以方便扩展任何数据。
inline CMemBuffer(int Size = 128)
{
  Init(Size);
}
内存池的构造函数。在内存池初始化时,构建一个拥有初始容量的内存池,以便在应用程序需要内存时,可以直接从池中获取。
这些内存由每个结点保持,并由pFreeHead指向头结点。
inline ~CMemBuffer()
{
  LinkNode<Type> * pItem = NULL;
  pItem = pFreeHead;
  while(pItem!=NULL)
  {
  pFreeHead = pItem->pNext;
  delete pItem;
  pItem = pFreeHead;
  }
  pFreeHead = pFreeTail = NULL;
}
内存池的析构函数,用于释放内存池中的所有内存。由于内存池中的内存都由结点元素所保持,释放结点既可释放内存。
inline LinkNode<Type> * AllocItem()
{
  LinkNode<Type> * pItem = NULL;
  m_cs_free.Lock();
  if(pFreeHead != NULL)
  {
  //删除队头元素
  pItem = pFreeHead;
  pFreeHead = pFreeHead->pNext;
  //如果头为NULL的话,则表示没有元素了,尾指针也必须赋值为NULL
  if(pFreeHead==NULL)
  {
  pFreeHead = pFreeTail = NULL;
  }
  }
  m_cs_free.Unlock();
  if(pItem==NULL)
  {
  pItem = new LinkNode<Type>();
  }
  memset(pItem,0,sizeof(LinkNode<Type>));
  return pItem;
}
从内存池中分配一个结点。这里拥有一个特别处理,就是当内存池中的结点被用完后,将从系统内存中分配结点返回给调用者,以实现内存池的自动扩充。
inline VOID FreeItem(LinkNode<Type> * pItem)
{
  pItem->pNext = NULL;
  m_cs_free.Lock();
  if(pFreeHead == NULL)
  {
  pFreeHead = pFreeTail = pItem;
  }
  else
  {
  pFreeTail->pNext = pItem;
  pFreeTail = pItem;
  }
  m_cs_free.Unlock();
}
当调用者通过AllocItem获得内存并使用后,必须通过调用这个函数来将结点释放给内存池,以便下次使用。
pFreeTail是指向最后一个结点的指针,为了链表管理更高效,所以添加一个尾结点的指针用来插入结点。
源码下载

------解决方案--------------------

------解决方案--------------------
呵呵,效率低了点
------解决方案--------------------
boost::pool
------解决方案--------------------
在Linux中内存管理的很好了,有必要要内存池吗?
------解决方案--------------------
lz,你看看这个 http://blog.csdn.net/chenyu2202863/archive/2010/08/17/5818929.aspx
------解决方案--------------------
顶一下,有交流才有提高

文章评论

10个调试和排错的小建议
10个调试和排错的小建议
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
中美印日四国程序员比较
中美印日四国程序员比较
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
我的丈夫是个程序员
我的丈夫是个程序员
旅行,写作,编程
旅行,写作,编程
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
程序员和编码员之间的区别
程序员和编码员之间的区别
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
每天工作4小时的程序员
每天工作4小时的程序员
漫画:程序员的工作
漫画:程序员的工作
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
Java程序员必看电影
Java程序员必看电影
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
那些争议最大的编程观点
那些争议最大的编程观点
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
看13位CEO、创始人和高管如何提高工作效率
看13位CEO、创始人和高管如何提高工作效率
编程语言是女人
编程语言是女人
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
我是如何打败拖延症的
我是如何打败拖延症的
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
十大编程算法助程序员走上高手之路
十大编程算法助程序员走上高手之路
聊聊HTTPS和SSL/TLS协议
聊聊HTTPS和SSL/TLS协议
 程序员的样子
程序员的样子
程序员应该关注的一些事儿
程序员应该关注的一些事儿
Web开发者需具备的8个好习惯
Web开发者需具备的8个好习惯
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
代码女神横空出世
代码女神横空出世
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
鲜为人知的编程真相
鲜为人知的编程真相
“懒”出效率是程序员的美德
“懒”出效率是程序员的美德
一个程序员的时间管理
一个程序员的时间管理
总结2014中国互联网十大段子
总结2014中国互联网十大段子
程序员的鄙视链
程序员的鄙视链
老程序员的下场
老程序员的下场
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有