STL源码剖析---内存池的实现
一、感想
2019年3月15日-3月23日,大概花了8天的时间,终于将SGI STL版本实现的内存池看懂了。不过内存池这个知识点大概在2018年8月份的时候就已经接触了,今天终于弄懂了,如卸心中之块垒!在此探讨的一些点,可能非常表面,如果需要深入了解,建议直接阅读《STL源码剖析·侯捷》相应章节。
二、思路
2.1 内存池
内存池只是使用两根指针 start_free 和 end_free 标记其范围的一段连续的堆空间而已,不负责对内存的分配与回收。因为一个内存池没有办法实现。内存分配与回收的具体工作交给一个 数组+链表 的结构去处理。我的本意是借着内存池这个切入点将 STL 中的空间配置器进行一个总结。
内存池的好处:1)时间效率高,如果每次需要动态申请内存都直接向system heap 索取,那么时间开销比较大;2)空间利用率高,每个从system heap 取得的区块都会包含记录本区块大小的头部信息,这也是没办法的事情。有了头部信息这个技巧,程序员释放空间的时候只需要告知系统一根指针即可,系统会自动根据头部读取到的数目进行空间的释放。如果不带头部信息,那么释放内存区块需要提供 指针+字节数,这对程序员来说负担过重,程序员得记下每次申请的空间的对应大小。如果维护在内存池中,就没有头部信息,空间利用率显著提高。在《STL源码剖析·侯捷》一书中关于头部信息使用了一个形象的比喻——“税”。
2.2 数组+链表
什么样的数组?什么样的链表?
每个数组元素代表一条链表,分别管理 8, 16, 24, 32, 40, 48, 56, 64, 72, 80, 88, 96, 104, 112, 120, 128 byte的小额区块。 大于128byte,直接使用malloc进行索取。
2.3 总结
内存池负责提供空间,数组+链表结构负责对空间进行管理(包含分配和回收)。三者相互协作,达到了效率上的最大化。