C++STL内存分配

STL文件的包含关系:

SGI STL 设计了双层级配置器。第一层配置器直接使用malloc() 和 free().第二层配置器则视情况采用不同的策略:但配置区块超过 128 bytes时,调用第一级配置器。当配置区块小于 128 bytes时,采用复杂的 memory pool 方式。下面我们分别简单的介绍一下第一级和第二级配置器。


第一级__malloc_alloc_template

第一级的配置比较简单,其实流程是这样的:

1.我们通过allocate()申请内存,通过deallocate()来释放内存,通过reallocate()重新分配内存。

2.当allocate()或reallocate()分配内存不足时会调用oom_malloc()或oom_remalloc()来处理。

3.当oom_malloc() 或 oom_remalloc()还是没能分配到申请的内存时,会转如下两步中的一步:

a).调用用户自定义的内存分配不足处理函数(这个函数通过set_malloc_handler() 来设定),然后继续申请内存!

b).如果用户未定义内存分配不足处理函数,程序就会抛出bad_alloc异常或利用exit(1)终止程序。

第二级配置__default_alloc_template

SGI第二级空间配置器较第一级空间配置器加入了内存池(memory pool)管理,即次层配置。当所申请的空间大于128bytes时,直接调用一级空间配置器处理,小于128bytes时,使用次层配置器管理。申请的空间不足8的倍数,默认提升为最近的8的整数倍的空间大小。

二级内存配置器(memory pool)的数据结构采用的是freelist的数组,其实这个数据结构实际上就是一个邻接表(表示‘图’的数据结构之一),只是组成数据结构的数据类型所表示的实际意义发生了一些变化。

数组的长度是16(128÷8=16),每个数组元素指向一个freelist头节点,所以memory pool实际上就是16个freelists。每个freelist是一个单链表,单链表中的每个结点代表固定字节数的内存块。比如第一个freelist(数组的头元素指向的freelist),表示由表示容量为8字节的内存块结点组成的单链表。那么按照数组顺序,依次代表的是16,24,32,40,48,56,64,72,80,88,96,104,112,120,128字节的freelist。


参考上图,假设我现在要申请大小为 56bytes 的内存空间,那么就会到free lists 的第 7 个元素所指的链表上去找。如果此时 #7元素所指的链表为空怎么办?这个时候就要调用refill()函数向内存池申请N(一般为20个)个大小为56bytes的内存区块,然后挂到 #7 所指的链表上。这样,申请者就可以得到内存块了。allocate()过程图如下:


deallocate()函数释放内存的步骤如下图:


资料来自:

https://blog.csdn.net/b711183612/article/details/84818777

https://zhuanlan.zhihu.com/p/31505598

你可能感兴趣的:(C++STL内存分配)