489-剖析SGI STL空间配置器

引言

不管是C的malloc free 还是C++的new delete,底层涉及内存管理调用的都是malloc,free,malloc和free是C的库函数。
如果我们在应用场景中涉及小块内存的开辟和释放,短时间内调用的次数特别多,由于malloc和free在进行内存管理的时候相对来说底层实现是比较复杂的。所以对于小块内存频繁的分配和释放,如果我们一直使用malloc和free,会对我们的应用程序的运行在内存管理的效率降低,此时,我们就要使用内存池的设计,对小块内存的频繁分配和释放进行内存池的管理,提高应用程序的性能。

SGI STL包含了一级空间配置器和二级空间配置器,其中一级空间配置器allocator采用malloc和free来管理内存,和C++标准库中提供的allocator是一样的,但其二级空间配置器allocator采用了基于freelist自由链表原理的内存池机制实现内存管理。

我们知道,C++STL中,STL是C++标准模板库,包含相应的头文件就可以使用。
SGI STL是一个第三方产商开发的STL,包含了全面的STL设计的组件。

C++ STL的allocator空间配置器

我们拿vector举个例子:
在这里插入图片描述
typename T是实例化vector容器的底层元素的类型。
第二个参数是传容器相应的空间配置器
我们发现Alloc有默认值,这个allocator就是C++标准库提供的默认allocator的实现(用户定义的时候不需要传)
我们可以这么定义:
在这里插入图片描述
allocate:负责给容器开辟内存空间—》调用malloc
deallocate:负责释放容器内存空间—》调用free
construct:负责给容器构造一个对象—》通过定位new实现(在容器已经开辟好的内存空间上构造一个新对象)
destroy:负责析构容器的对象—》通过p->~T()

空间配置器的核心作用:分离了对象的内存开辟和对象构造。这2件事情原本由一个普通的new就做完了,但是对于容器来说不合适,所以通过空间配置器的以上方法来管理。
也分离了对象的析构和内存的释放

SGI STL的空间配置器

提供了2个allocator的实现:一级空间配置器allocator,二级空间配置器allocator

一级空间配置器allocator:内存管理,是使用malloc和free。
二级空间配置器allocator:内存管理,是基于内存池的实现。

我们看看SGI STL的vector容器实现

在这里插入图片描述
也给了一个默认的allocator。

我们看看push_back函数,逻辑上应该是在容器底层已经有的内存上去构造一个对象出来。在SGI STL是通过construct函数实现对象的构造,没有通过容器空间配置器。_M_finish是容器的最后一个元素的后继位置。

在这里插入图片描述

我们进入到construct函数看看
在这里插入图片描述
是全局的函数模板,我们再进入到_Construct函数里面
在这里插入图片描述
实际上还是定位new 和C++STL的construct做的事情一样。

我们看看pop_back()函数:
在这里插入图片描述
也没有使用容器的空间配置器,使用的也是全局的destroy函数。
在这里插入图片描述
我们进去看看:
在这里插入图片描述
通过指针,这个指针指向需要析构的对象,调用当前对象的析构函数,不会释放容器的内存的。因为构造函数,析构函数的名字和类型的名字是一样的。

SGI STL的容器vector底层存储的对象的构造和析构是通过定义的全局的函数模板construct和destroy完成的。

STL的空间配置器现在只剩下这 2个操作:
allocate:负责给容器开辟内存空间—》malloc
deallocate:负责释放容器内存空间—》free
就是内存的管理!!!

SGI STL二级空间配置器重要成员

在这里插入图片描述
Alloc类型给的是宏定义,是把实例化容器的元素的类型Tp当做参数传进来
在这里插入图片描述

我们再进去到allocator:
在这里插入图片描述
我们看看它的一些操作的实现:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
这些实现和C++ STL的一样

我们再进去看看_Alloc封装的allocate和deallocate,肯定也是malloc和free,就是一级空间配置器的实现。

在这里插入图片描述
我们进去看看malloc_alloc:
在这里插入图片描述
我们再进去__malloc_alloc_template:

在这里插入图片描述
我们可以判定,它的一级空间配置器相当于C++的标准库的allocator
在这里插入图片描述

如果没有宏,SGI用的是二级空间配置器alloc

在这里插入图片描述

在这里插入图片描述
所以SGI STL默认的是二级空间配置器,我们看第一个参数:
在这里插入图片描述
代表的意思是“节点分配是否支持线程安全:
在这里插入图片描述
基于内存池实现的容器空间配置器可以直接使用在多线程环境下,是线程安全的。

在C++STL下,不管是容器还是空间配置器,其他组件设计,的时候都没有考虑线程安全的。

但是SGI STL则是有线程安全。
刚才讲的这些都在stl_alloc.h定义的
在这里插入图片描述

总结

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

林林林ZEYU

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值