c++空间配置器

引言

  我们在使用STL的容器时,会发现容器中的数据在到达一定数量时,就会进行扩容操作,也就会申请空间。频繁的进行扩容时,就会频繁地向操作系统申请空间,这样极大的影响了操作系统地效率。为了解决这一问题,操作系统就说,我直接给你一块内存空间,你就从这块内存空间申请和释放内存,就不用直接过来找我了,里面的内存不够了再来找我。于是,就有了空间配置器这一概念。所以总的来说,空间配置器就是是 C++ 中用于管理内存分配和释放的机制,在STL库中,容器和其他一些组件都会使用空间配置器来分配和管理内存。

结构

  空间配置器有两级结构,一级空间配置器是用来处理大块内存,而二级空间配置器则处理小块内存。SGI-STL规定以128字节作为小块内存和大块内存的分界线

为什么这么分呢?
  因为STL容器一般申请的都会是小块的内存,也就是小于128字节的内存,旨在解决频繁向系统申请小块内存时出现的问题;如果申请的空间大于128字节则调用一级空间配置器。

一级空间配置器

原理

  底层对malloc与free进行封装,引入c++中的set_new_handle思想,该思想是提供一种机制来处理内存分配失败的情况,总的来说就是如果内存分配失败,‌它会调用一个处理函数来尝试解决问题,‌比如释放一些资源或采取其他适当的措施,‌以避免抛出异常。

二级空间配置器

  前面我们说到二级空间配置器处理小块内存,即小于128字节的内存。而在SGI-STL中采用了内存池的技术来提高申请空间的速度。

内存池技术
  内存池技术是一种内存管理技术,‌主要用于优化程序中动态内存分配和释放的效率,‌减少内存碎片,‌提高程序运行速度。‌内存池通过预先分配一大块内存,‌留作备用,‌当申请内存时,‌从池中取出一块动态分配,‌当释放时,‌将释放的内存放回到池内,‌再次申请就可以从池里取出来使用。‌这种技术旨在提高资源的利用率,‌保证程序占有的资源数量,‌同时减少由于频繁申请和释放内存导致的内存碎片问题,‌从而提高程序和操作系统的性能。

与此同时也出现了一个问题,就是归还内存的时候,不知道该内存原来在内存池中的位置,也就无法归还,于是我们引入哈希桶这一个概念

哈希桶技术
  哈希桶技术是哈希表实现中的一种数据结构,‌用于解决哈希冲突问题。‌哈希桶的工作原理基于链地址法,‌即当发生哈希冲突时,‌新的键-值对可以直接插入到相应的桶中,‌形成一个键-值对的链表。‌这种实现方式允许在一个桶中存储多个键-值对,‌从而提高了查找效率。‌
在这里插入图片描述

那我们需要用128个桶对这128字节的每个字节的空间进行管理吗?
事实上,在SGI-STL中只用到了16个哈希桶,即每个哈希桶管理128/16=8字节。事实上在大部分时候,用户申请的空间基本上都是4的整数倍,那为什么是8而不是4呢?因为前面我们提到哈希桶的工作原理基于链地址法,即通过链表将所有内存块连接,所以每个内存块需要保存下一个内存块的地址,而我们知道地址在64位系统下刚好为8字节。

内存碎片

分为外碎片和内碎片

外碎片

   外部碎片则指的是还没有被分配出去的内存空闲区域,‌但由于这些空闲区域太小,‌无法分配内存空间。‌这些存储块位于已分配区域的外部,‌它们的总内存可能满足当前申请的长度要求,‌但由于地址不连续,‌系统无法满足当前申请。‌由于用户频繁地申请小块内存,使得整块内存中被申请的内存块不连续,导致某次申请内存时如果需要申请一大块内存,内存空间够,但是由于不连续,无法申请到。

内碎片

   内部碎片指的是已经被分配出去却不能被利用的内存空间。‌这些存储块位于区域或页面的内部,‌即使进程占有了这些存储块,‌系统也无法利用它们,‌直到进程释放或结束时,‌系统才可能利用这些存储块。‌内存申请时按一定规则对齐,就会导致内存碎片给的内存数比实际要的内存数多,导致空间浪费。事实上SGI-STL将用户申请的内存块向上对齐到了8字节的整数倍,就造成了内碎片问题。

总结

  当容器进行扩容时,如果申请的空间是大于128字节,直接向一级空间配置器申请。如果小于128字节,则先查找哈希桶对应大小位置是否为空,若不为空,则直接从该位置申请空间,如果该位置为空,向内存池申请。当用户向内存池申请一块大小为n的空间时,为了提高效率,内存池会切割若干块大小为n的空间,将其中一个分配给用户,其余的会连接到哈希桶对应下标处,避免下一次查找哈希桶对应大小位置为空。当内存池空间不够了则向操作系统申请空间;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值