剖析SGI STL空间配置器(空间配置器的重要性和重要成员及函数)

剖析SGI STL空间配置器

在我们使用STL容器的时候,模板最后一个参数会有一个默认的allocator作为容器模板的参数,这个参数就是STL的空间配置器。容器的空间配置器见这篇文章:容器空间配置器的重要性
STL容器空间配置器实际上就是拆分了new关键字的两个步骤:内存申请和构造对象;和delete的内存释放和对象析构。其底层的内存管理调用的都是malloc和free。
C++STLvector容器的构造函数:
在这里插入图片描述
有一个默认的模板参数,我们使用的时候是不需要传的,他有四个重要的函数:
allocate:负责给容器开辟内存空间,实际上调用就是malloc
deallocate:负责释放容器开辟的内存,实际上调用的就是free
construct:负责给容器构造一个对象,实际上就是用定位new实现
destory:负责析构容器的一个对象,实际上就是调用对象的析构函数,~p->_Ty();

如果我们的应用场景中涉及小块内存的开辟和释放,短时间内调用的次数特别多,而malloc和free的底层实现是比较复杂的。如果我们频繁地对小块内存分配和释放一直使用malloc和free,不仅会拖慢我们地程序运行效率,还会产生很多的内存碎片。
SGI STL空间配置器就是为了解决这个问题,它分为一级空间配置器和二级空间配置器,其中一级空间配置器用malloc和free来管理内存,和C++STL标准模板库的空间配置器是一样的。而二级空间配置器采用了基于freelist自由链表的形式,以内存池机制来实现小块内存的管理。
STL是C++的标准模板库,而SGI STL是一个第三方厂商开发的STL,包含了STL设计的组件。

查看SGI STLvector容器的定义:
在这里插入图片描述在这里插入图片描述
可以看到也给了一个默认的allocater,查看这个宏我们可以看到,我们可以通过定义宏__STL_USE_STD_ALLOCATORS来控制用不用SGI STL提供的alloc,查看vector的push_back操作:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以看到其容器元素的构造和STL的动作是一致的,通过定位new来实现的。同理,_Destory函数调用的就是对象的析构函数。

SGI STL和C++STL空间配置器的对象构造和对象的析构都一致,不同的主要是在内存开辟和释放。

查看SGI STL的空间配置器的空间配置器alloc
在这里插入图片描述
在这里插入图片描述
可以完整的看到它所包含的参数,下面一一对这些参数进行剖析。

  • _ALIGN:翻译过来就是对齐,小块内存的分配默认是以8字节对齐的,分配内存是系统位数的整数倍可以加快内存的分配速度
  • _MAX_BYTES:小大块内存的分界,默认最大的小块内存
  • _NFREELISTS:自由链表的长度,等于_MAX_BYTES/_ALIGN
  • _S_round_up函数:提升小块内存的大小提升到8的倍数,比如申请(1~7)字节的空间,会提升到8字节,然后分配8字节出去,方便内存的管理和分配速度,返回实际申请的内存大小,
  • union _Obj:链表结构的联合体,用来记录未分配的内存块
  • _S_free_list:自由链表数组,存储不同8~128内存块的头节点,长度为_NFREELISTS,也就是16
  • _S_freelist_index函数:获取对应大小内存块在自由链表的下标并返回

除了这些参数,类外还定义了一些函数来维护内存池
在这里插入图片描述

  • _S_refill函数:分配一个chunk块,大小为__n,传参时需要先调用_S_round_up函数提升到8的倍数
  • _S_chunk_alloc函数:内存池的内存来源,chunk块不足时从这里填充,备用池不足时malloc申请,malloc失败还可以调用预先设置的回调函数释放内存
  • _S_start_free:维护备用内存池的起始地址,初始化为空
  • _S_end_free:维护备用内存池的末尾地址,初始化为空
  • _S_heap_size:记录上次填补备用池的大小,初始化为0

其结构初始化如下图所示:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

_200_

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

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

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

打赏作者

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

抵扣说明:

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

余额充值