Just enjoy programming

STL源码分析空间配置器

       看过STL空间配置器的源码,总结一下:
      (1)STL空间配置器:主要分三个文件实现,stl_construct.h  这里定义了全局函数construct()和destroy(),负责对象的构造和析构。stl_alloc.h文件中定义了一,二两级配置器,彼此合作,配置器名为alloc. stl_uninitialized.h 这里定义了一些全局函数,用来填充(fill)或复制(copy)大块内存数据,他们也都隶属于STL标准规划。
      在stl_alloc.h中定义了两级配置器,主要思想是申请大块内存池,小块内存直接从内存池中申请,当不够用时再申请新的内存池,还有就是大块内存直接申请。当申请空间大于128字节时调用第一级配置器,第一级配置器没有用operator::new和operator::delete来申请空间,而是直接调用malloc/free和realloc,并且实现了类似c++中new-handler的机制。所谓c++ new handler机制是,你可以要求系统在内存配置需求无法被满足时,调用一个指定的函数。换句话说,一旦::operator::new无法完成任务,在丢出std::bad_alloc异常状态之前,会先调用由客端指定的处理例程,该处理例程通常称为new-handler.new-handler解决内存做法有特定的模式。SGI第一级配置器的allocate()和realloc都是在调用malloc和realloc不成功后,改调用oom_malloc()和oom_realloc().后两者都有内循环,不断调用"内存不足处理例程",期望在某次调用之后,获得足够的内存而圆满完成任务。但如果“内存不足处理例程“并未被客端设定,oom_malloc()和oom_realloc便调用_THROW_BAD_ALLOC, 丢出bad_alloc异常信息,或利用exit(1)硬生生中止程序。
     在stl_alloc.h中定义的第二级配置器中,如果区块够大,超过128字节时,就移交第一级配置器处理,当区块小于128字节时,则以内存池管理,此法又称为次层配置,每次配置一大块内存,并维护对应的自由链表(free-list).下次若再有相同大小的内存需求,就直接从free-list中拔出。如果客端释还小额区块,就由配置器回收到free-lists中,配置器除了负责配置,也负责回收。为了管理方便,SGI第二级配置器会主动将任何小额区块的内存需求量上调至8的倍数。并维护16个free-lists,各自管理大小分别为8,16,24,32,40,48,56,64,72,80,88,96,104, 112,120,128 字节的小额区块。当申请小于等于128字节时就会检查对应的free list,如果free-list中有可用的区块,就直接拿来,如果没有,就准备为对应的free-list 重新填充空间。新的空间将取自内存池,缺省取得20个新节点,如果内存池不足(还足以一个以上的节点),就返回的相应的节点数.如果当内存池中连一个节点大小都不够时,就申请新的内存池,大小为2*total_bytes+ROUND_UP(heap_size>>4), totoal_bytes 为申请的空间大小,ROUND_UP调整为8的倍数,heap_size为当前总申请内存池的大小。如果申请该内存池成功就把原来内存池中剩下的空间分配给适当的free-list.万一山穷水尽,整个system heap空间都不够了(以至无法为内存池注入源头活水),malloc()行动失败,就会四处寻找有无"尚有未用区块,且区块足够大 "之free lists.找到了就挖一块交出,找不到就调用第一级配置器。第一级配置器其实也是使用malloc来配置内存。但它有out-of-memory处理机制(类似new-handler机制),或许有机会释放其他的内存拿来此处使用。如果可以就成功,否则发出bad_alloc异常。

参考:STL源码分析

posted on 2011-05-12 10:19 周强 阅读(2645) 评论(7)  编辑 收藏 引用 所属分类: c++ STL源码分析

评论

# re: STL源码分析空间配置器 2011-05-12 20:08 空明流转

这么复杂,肯定比 CRT的malloc慢。  回复  更多评论   

# re: STL源码分析空间配置器 2011-05-12 22:10 周强

@空明流转
这种内存池主要思想是申请大块内存池,小块内存直接从内存池中申请,当不够用时再申请新的内存池,还有就是大块内存直接申请。虽然有点复杂,我感觉不会太慢,减少 malloc与free的调用,而且可以减少内存碎片。 CRT的malloc的我没用过,所以我也不知道具体哪个会比较好。  回复  更多评论   

# re: STL源码分析空间配置器 2011-05-13 09:15 空明流转

@周强
malloc free 有两个部分,库提供接口和部分实现,OS提供另外一部分实现。
在Vista之后,以及在Linux上,Malloc和Free的速度已经比什么所谓的内存池要快的多了。你会做的优化,那些写操作系统和库的牛人能不会?  回复  更多评论   

# re: STL源码分析空间配置器 2011-05-13 23:29 周强

@空明流转
哦,你说得挺对的。呵呵,以后多向你学习学习。  回复  更多评论   

# re: STL源码分析空间配置器[未登录] 2011-07-05 09:44 Chipset

malloc和free要比内存池慢得太多,而且碎片率也高,不论什么系统。试一试就知道了。
但是话又说回来,能写一个有实用价值的内存管理器的人世界上就有数的那么几个,屈指可数。SMP的有jemalloc, Hoard, Ptmalloc3, Cmalloc...它们的进化源头分别来自phkmalloc, (独立的堆层次理论), dlmalloc, dlmalloc...,说白了无非就三个,古老的Unix上用的phkmaloc,通俗意义上的dlmaloc,还有土生土长自己独立开发出来的Hoard,其它的全是衍生品。

什么大牛小牛都是扯淡,看看微软和Intel怎么给Hoard拍马屁就知道了。  回复  更多评论   

# re: STL源码分析空间配置器[未登录] 2011-07-05 09:47 Chipset

SGI STL这个小内存算不上什么内存管理器,只是小牛试刀罢了。  回复  更多评论   

# re: STL源码分析空间配置器 2011-07-05 10:26 周强

@Chipset
恩,说得很有道理,学习了。  回复  更多评论   


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理