STL内存池以及vector的原理

本文探讨了STL中的vector如何进行内存分配,尤其是其动态增长机制,以及STL内存池的概念和作用。当vector扩展时,它会重新申请内存并复制元素,导致原有迭代器失效。内存池通过预分配内存来提高小块内存申请和释放的效率,减少内存碎片。在STL中,内存管理分为两级配置器,对于小于128字节的内存请求,采用内存池策略,维护16个空闲链表进行管理。

vector是一种容器,一种顺序容器,它的内存分配是连续的。与数组不同的是,数组的大小是静态的,不能动态的扩展,但是vector却可以。

vector的扩充机制:按照容器现在容量的一倍进行增长。vector容器分配的是一块连续的内存空间,每次容器的增长,并不是在原有连续 的内存空间后再进行简单的叠加,而是重新申请一块更大的新内存,并把现有容器中的元素逐个复制过去,然后销毁旧的内存。这时原有指向旧内存空 间的迭代器已经失效,所以当操作容器时,迭代器要及时更新。
 

STL - 内存分配 - 内存池

各种池子的作用在前面的文章讲过,本质上都是为了增加性能效率,内存池也一样,有的时候有很多频繁的小的内存申请和释放,如果没次都去向系统申请则会耗费很多时间,影响效率。因此需要内存池来过滤一些短小的内存操作。当然还有一个原因就是会引起内存碎片的问题。

STL的内存池的详细实现可以参考STL源码剖析当中的allocator一章。下面我们简单讲解下大致原理。

STL中的内存管理 当我们new一个对象时,实际做了两件事情:(1)使用malloc申请了一块内存。(2)执行构造函数。在SGI中,这两步独立出了两个函数:allocate申请内存,construct调用构造函数。这两个函数分别在<stl_alloc.h>和<stl_construct.h>中。


二、第一级配置器 第一级配置器以malloc(),free(),realloc()等C函数执行实际的内存配置、释放、重新配置等操作,并且能在内存需求不被满足的时候,调用一个指定的函数。

三、第二级配置器 在STL的第二级配置器中多了一些机制,避免太多小区块造成的内存碎片,小额区块带来的不仅是内存碎片,配置时还有额外的负担。区块越小,额外负担所占比例就越大。

    如果要分配的区块大于128bytes,则移交给第一级配置器处理。     如果要分配的区块小于128bytes,则以
内存池管理(memory pool),又称之次层配置(sub-allocation):每次配置一大块内存,并维护对应的16个空闲链表(free-list)。下次若有相同大小的内存需求,则直接从free-list中取。如果有小额区块被释放,则由配置器回收到free-list中。

(1)空闲链表的设计 这里的16个空闲链表分别管理大小为8、16、24......120、128的数据块。这里空闲链表节点的设计十分巧妙,这里用了一个联合体既可以表示下一个空闲数据块(存在于空闲链表中)的地址,也可以表示已经被用户使用的数据块(不存在空闲链表中)的地址。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

编程经验随笔

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

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

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

打赏作者

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

抵扣说明:

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

余额充值