stl内存池学习(一)——内存池初认识

      最近开始学习内存池技术,《高质量c++/c编程指南》在内存管理的第一句话就是:欢迎进入内存这片雷区,由此可见掌握内存管理对于c++/c程序员的重要性。使用内存池的优点有:降低动态申请内存的次数,提升系统性能,减少内存碎片,增加内存空间使用率。
      内存池的分类:
      一、不定长内存池:优点:不需要为不同的数据创建不同的内存池,缺点是分配出去的内存池不能回收到池中(?)。代表有apr_pool,obstack。
      二、定长内存池:优点:使用完立即把内存归还池中。代表有Loki, Boost。
      本次以sgi stl中实现的内存池作为学习对象。由于要实现的是一个C语言的内存池,所以这里用C的描述方式。喜欢C++的朋友可以直接看源文件或者《STL源码剖析》的讲解。sgi设计了二级配置机制,第一级配置器直接使用malloc()和free()。当配置区块超过128 bytes时,则采用第一级配置器;否则采用memory pool方式。
      memory pool的整体思想是维护128/8 = 16个自由链表,这里的8是小型区块的上调边界。每个自由链表串接的区块大小如下:

序号 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
串接区块 8 16 24 32 40 48 56 64 72 80 88 96 104 112 120 128
范围 1-8 9-16 17-24 25-32 33-40 41-48 49-56 57-64 65-72 73-80 81-88 89-96 97-104 105-112 113-120 121-128

 

 

 

      几个过程的思路:
      一、申请过程:

Code:
  1. if (用户申请的内存不大于128 bytes)   
  2.     查找对应的链表   
  3.     if (对应链表拥有一块以上的区块)   
  4.         调整链表   
  5.         返回第一个区块地址   
  6.     else  
  7.         准备重新填充链表   
  8.             向内存池申请内存(指定数量的区块)   
  9.             if (内存池申请到一个区块)   
  10.                 返回第一个区块地址   
  11.             else  
  12.                 调整链表,将区块串接起来   
  13.                 返回第一个区块地址   
  14. else  
  15.     直接用malloc()申请内存  

        二、释放过程:

Code:
  1. if (用户释放的内存块大于128 bytes)   
  2.     直接用free()释放   
  3. else  
  4.     查找对应的链表   
  5.     回收内存  

       三、向内存池申请内存过程:

Code:
  1. if (内存池空间完全满足需求量)   
  2.     调整内存池起始位置   
  3.     返回空间地址   
  4. else if (内存池空间不能完全满足需求量,但能提供一个以上的区块)   
  5.     计算能够提供的最大内存   
  6.     调整内存池起始位置   
  7.     返回空间地址   
  8. else  
  9.     从内存池中压缩内存   
  10.     收集比size大的空间   
  11.     递归调用,修正nobjs   
  12.     再次申请内存,可能抛出异常  

你可能感兴趣的:(stl内存池学习(一)——内存池初认识)