SGI STL内存配置器存在内存泄漏吗?

阅读了SGI的源码后对STL很是膜拜,很高质量的源码,从中学到了很多。温故而知新!下文中所有STL如无特殊说明均指SGI版本实现。

STL 内存配置器

STL对内存管理最核心部分我觉得是其将C++对象创建过程分解为构造、析构和内存分配、释放两类操作分离开来!摆脱了对频繁调用new或malloc函数想操作系统申请空间而造成的低效。其中析构操作时对具有non-trival、trival 析构函数的class区别对待也提高了效率。SGI 的两级配置器结构属于锦上添花。

STL内存配置器有没有内存泄漏?

STL两级结构的配置器使得STl能对小的空间内存分配管理更为合理,而很多人有疑问的时这个对小空间的配置器是否存在内存泄漏?“源码面前了无秘密”问题来于源码自,答案也在源码之中。先概述一下STL两级结构的配置器是怎么操作的,STL的Allocator中队内存的申请和释放均是通过其两个静态成员函数完成,allocate,deallocate;对于大于128Byte的内存申请和释放,两个函数均通过调用malloc和free来实现。当内存不大于138Byte时,该allocator会通过一个链表和内存池来维护空间。很多人疑惑为什么在该Allocator的实现里只有对内存池malloc的代码,没看到类似free这样释放内存的代码,甚至该Allocator类都没有析构函数,这样不是会存在内存泄漏吗?其实不然,对于由链表维护的内存,其内存的释放工作应该是上一层调用者负责,比如容器Vector在析构函数中就显示的将其申请的所有capacity大小的内存释放。内存池则不一样,内存池的中的内存将会一直保留知道程序退出。有的同学可能会认为“这不就是内存泄漏吗?比如一个创建了一个Vector变量,到Vector析构了之后再内存中竟然有一块内存没有被系统回收,这不就是内存泄漏吗”,其实不然:

1. 申请的内存没有被及时释放不等于内存泄漏

在单线程中,由于该Allocator中记录内存池起始的指针是静态类型,所以只要是你在同一个线程中,无论你创建多少个Allocator,记录内存池的变量都是同一个,换句话说,当下次再创建Vector时,还是使用上一次使用的那个。

2. 该内存池不会疯狂野生长

这个内存池的空间其实是很小的,因为大于128Byte的内存申请都直接转调了malloc,从源码中也可以看出,内存池每次重新灌水的新容量是2*total_size + round_up(heap_size >> 4)。

内存池的存在是为了避免大量内存碎片的产生,代价是管理内存所需要多付出的时间和空间消耗。

以上就是内存池一种存在直至程序退出的原因。

在GCC 5.4.0 中的使用的SGI已经对该种设计做了大幅修改。1. 默认的Allocator也不在是侯捷一书中说指出的具有内存池的配置器,而是"\usr\include\c++\5\ext\new_allocator.h"其实现直接调用new;2. 而之前相应的具备内存池的配置器则被当做STL的扩展,实现于"\usr\include\c++\5\ext\pool_allocator.h"中,且该实现不在存在内存池的设计,只保留了使用链表将小内存块连接起来的设计(使用时记得include该文件路径,命名空间为__gnu_cxx::__pool_alloc<int> )。

在llvm中Allocator的实现也是直接调用new。

FYI:

GCC更换Allocator设计,http://www.cppblog.com/peakflys/archive/2015/01/14/209513.html

SGI源码,https://www.sgi.com/tech/stl/download.html

SGI源码,allocator,https://www.sgi.com/tech/stl/stl_alloc.h

SGI源码,vector,https://www.sgi.com/tech/stl/stl_vector.h

时间: 2024-10-06 00:10:50

SGI STL内存配置器存在内存泄漏吗?的相关文章

内存配置器

stl中内存配置器分为两级:第一级配置对象超过128B的内存,第二级配置对象小于128B的内存,stl默认采用第二级内存配置器,因为如果对象大于128B,则第二级内存配置器会自动调用第一级内存配置器. 第一级内存配置器简单的对malloc,realloc,free的封装 第二级内存配置器采用内存池管理内存,并用16个链表管理回收到的空闲内存块,当分配内存时,首先找到合适位置的空闲链表,若链表上有空闲内存块,则直接摘下空闲内存块供使用;否则就需要向内存池申请新的空闲内存块,若内存池都没有剩余内存了

STL空间配置器(一)

STL空间适配器(一) Author:胡建 Time:2016/4/5 这是STL学习的第一部分,空间适配器,所谓空间适配器,就是用来管理内存的一个器具.对于STL来说,空间适配器是它可以正常工作的基础,也为它可以高效工作提供了动力.对于使用STL来说,它是不和用户直接打交道的,而是隐藏在一切STL组建之后,默默为各种内存申请提供支持的. 对于c++用户来说,new和delete很熟悉,这两个函数可以分别完成内存的申请和释放,和c里面的malloc和free如出一辙,SGI 有一个标准空间适配器

STL——空间配置器(SGI-STL)

一. 空间配置器标准接口 参见<STL源码剖析>第二章-2.1. 二.具备次配置力的SGI空间配置器 SGI STL的配置器与众不同,也与标准规范不同,其名称是alloc而非allocator,而且不接受任何参数(虽然SGI也定义有一个符合部分标准.名为sllocator的配置器,但SGI自己从未用过它,也不建议使用,主要因为效率不佳).这并不会带来什么困扰:我们通常很少需要自行指定配置器名称,而SGI STL的每一个容器都已经指定其缺省的空间配置器为alloc. // 在程序中要明白采用SG

SGI STL内存配置器(一):内存泄漏?

阅读了Alexander大神的SGI STL源码,膜拜,很高质量的源码,获益匪浅.温故而知新!下文中所有STL如无特殊说明均指SGI版本实现. STL 内存配置器 STL对内存管理最核心部分我觉得是它将C++对象创建过程分解为构造.析构和内存分配.释放!摆脱了由于频繁调用new或malloc函数向操作系统申请空间而造成的低效.其中析构操作时对具有non-trival.trival 析构函数的class区别对待也提高了效率.至于SGI的两级配置器结构则属于锦上添花的类型. STL两级结构的内存配置

自己动手实现STL 01:内存配置器的实现(stl_alloc.h)

一.前言 在STL中,容器是其中的重中之重,基本的STL中的算法,仿函数等都是围绕着容器实现的功能.而,内存配置器,是容器的实现的基础.所以,我第一次要去编写便是内存配置器的实现.在STL中,内存配置器的实现是在stl_alloc.h中. 二.配置器原理简要介绍 在SGI STL中配置分为两级,第一级配置器和第二级配置器.两者关系如下: 图1:第一级配置器和第二级配置器 在SGI STL中内存的配置器分为两级,第一级配置器和第二级配置器.第一级配置器就是,直接调用系统的malloc分配内存.对于

STL容器内存配置器

本系列文章更多是笔记形式,希望能在总结过程中将一些东西理顺.难免出错,欢迎指正. STL六大功能组件: 1.容器(containers):2.算法(algorithm):3.迭代器(iterator):4.仿函数(functors):5.配接器(adapters):6.配置器(allcators). 各个功能组件间存在交互关系,这里不涉及这些内容,本篇文章讨论容器的内存配置. 首先,容器用来存放数据,那么存放数据之前必须向系统申请内存资源.我们知道c++中通常用(::operator new/:

c++ stl 内存配置器

在STL中,Memory Allocator 处于最底层的位置,为一切的 Container 提供存储服务,是一切其他组件的基石.对于一般使用 STL 的用户而言,Allocator 是不可见的,如果需要对 STL 进行扩展,如编写自定义的容器,就需要调用 Allocator 的内存分配函数进行空间配置. 在C++中,一个对象的内存配置和释放一般都包含两个步骤,对于内存的配置,首先是调用operator new来配置内存,然后调用对象的类的构造函数进行初始化:而对于内存释放,首先是调用析构函数,

STL内存配置器

一.STL内存配置器的总体设计结构 1.两级内存配置器:SGI-STL中设计了两级的内存配置器,主要用于不同大小的内存分配需求,当需要分配的内存大小大于128bytes时, 使用第一级配置器,否则使用第二级配置器:对于小块的内存的分配使用第二级配置器使用分配与释放内存块的效率更高,时间复杂度为O(1): 2.两级配置器的优点: (1)使用两级配置器主要是为了避免太多的小块的内存申请导致内存空间中的内存碎片问题: (2)使用第二级配置器也可以避免太多小块内存分配导致的内存空间浪费问题,因为在申请内

stl空间配置器线程安全问题补充

摘要 在上一篇博客<STL空间配置器那点事>简单介绍了空间配置器的基本实现 两级空间配置器处理,一级相关细节问题,同时简单描述了STL各组件之间的关系以及设计到的设计模式等. 在最后,又关于STL空间配置的效率以及空间释放时机做了简单的探讨. 线程安全问题概述 为什么会有线程安全问题? 认真学过操作系统的同学应该都知道一个问题. first--进程是系统资源分配和调度的基本单位,是操作系统结构的基础,是一个程序的运行实体,同时也是一个程序执行中线程的容器 seconed--进程中作为资源分配基