第一级空间配置器

  第一级配置以malloc(), free(), realloc()等c函数执行实际的内存配置,释放、重配置操作,并实现出类似c++ new handler的机制。它不能直接使用c++ new handler机制,因为它并非使用::operator new来配置内存。

  所谓的c++ new handler机制,就是你可以要求系统在内存配置需求无法被满足时,调用一个你所指定的函数。换句话说,一旦::operator new无法完成任务,在丢出std::bad_alloc异常状态之前,会调用一个由客户端指定的处理例程。该处理例程被称为c++ new handler。new handler解决内存不足的做法有特定的模式。

  //oom指:out of memory

  SGI以malloc而不是::operator new来配置内存,因此SGI不能直接使用C++的set_new_handler(),必须仿真一个类似的set_new_handler()。SGI低一级配置器的allocate()和realloc() 都是在调用malloc()和realloc()不成功之后,改调用oom_malloc()和oom_realloc()。后两者都有内循环,不断调用“内存不足处理例程”,期望在某次调用之后获得足够的内存圆满完成任务。但是如果“内存不足处理例程”并未被客户端设定,oom_malloc()和oom_realloc()便会调用_THROW_BAD_ALLOC,丢出bad_alloc异常信息,或利用二线exit(1)直接终止程序。

第二级空间配置器

  第二级配置器多了一些机制,避免太多小额区块造成内存的碎片。小额区块带来的其实不仅仅是内存碎片,配置时的额外负担(overhead系统开销(计算机网络)overhead,在计算机网络帧结构中,除了有用数据以外,还有很多控制信息,这些控制信息用来保证通信的完成。这些控制信息被称作系统开销。)也是一个大问题。额外负担永远无法避免,毕竟系统要靠这多出来的空间来管理内存。

  SGI第二级配置器的做法是,如果区块够大,超过128bytes时,就移交给第一级配置器处理。当区块小于128bytes时,则以内存池(memory pool)的方式管理,此法又称之为层次配置(sub_allocation):每次配置一大块内存,并维护对应的自由链表(free list)。下次若再有相同大小的内存需求,就直接从free-lists中拨出。如果客户端释放了小额区块,也负责回收。为了方便管理,SGI第二级配置器会主动将任何小区块的内存需求量上调至8的倍数(如需求为30bytes,自动调整为32bytes)。并维护16(128/8=16)个free-lists,各自管理的大小为8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128的小额区块。

  free-lists的结构如下:

union obj{

union obj * free_list_link;

char client_data[1];   /*the client sees this.*/

    }

  大家可能会想为了维护链表,每个节点都需要额外的指针指向下一个节点,这不又造成了另一种额外负担么?但是请注意,上述obj所用的是union,所以从其第一个字段来看,obj可以被当做一个指向形式相同的另一个obj的指针;从第二个字段来看,可以把它看做指向实际区块的指针。

内存分配策略:

叙述之前做一下约定:

req_size ,表示用户请求的内存大小。

_round_up(size_t size),表示对用户请求的内存大小,向上调整为8的倍数。

例如:req_size = 14 , 那么_round_up(req_size ) 的返回值是16。

_pool_watermark(size_t size),表示用户请求的内存在head_list中的下标。

例如:req_size = 14 , 那么_pool_watermark(req_size ) 的返回值是1。

具体策略:
1)如果用户申请超过128字节的内存,则直接调用第一级简单空间配置器;否则,执行2)。

2)小于128bytes就检测对应的free-lists,如果free list之内有可用的区块,就直接返回给用户。如果没有可用区块,就将区块大小上调至8的倍数边界,然后调用refill(),准备为free list重新填充空间。

内存池取空间操作

从内存池中取空间给free
list,是chunk_alloc()的工作。其工作流程如下:

chunk_alloc()中以end_free
– start_free 来判断内存池是的剩余内存。

1, 
如果内存充足,则直接调出20个区块返回给对应的free list。

2, 
如果内存不足,但是end_free – start-free的值仍然大于size,即可以提供一个以上的区块,就提供这不足20的区块出去,这时候pass by reference 的nobjs参数将被修改为实际供应的区块个数。

3, 
如果剩余内存不足提供一个区块,则调用malloc从heap中分配内存给内存池。

  a) 如果heap足够,则分配20*2+n(n为附加量,随着分配次数的增加而增加)的内存块给内存池,其中第一个给用户,19个给free list维护,剩余的20+n个给内存池维护。

  b) 如果heap也没了,malloc失败,chunk alloc()就搜寻整儿free list看是否有“尚未利用的区块,且区块足够大”,如果有则分配给用户。

  c) 如果没搜寻到,则调用第一级空间配置器。第一级空间配置器也采用的是malloc,但是第一级空间配置器有out of memory处理机制(类似new handler处理机制),或许有机会释放出内存,如果可以就成功,否则抛出bad_alloc异常。

内存释放策略

如果释放的内存超过128字节,则调用“简单空间配置器”的内存释放函数。否则,找出对应的free list,将区块收回。

[stl] SGI STL的空间配置器的更多相关文章

  1. STL源码剖析 — 空间配置器(allocator)

    前言 以STL的实现角度而言,第一个需要介绍的就是空间配置器,因为整个STL的操作对象都存放在容器之中. 你完全可以实现一个直接向硬件存取空间的allocator. 下面介绍的是SGI STL提供的配 ...

  2. STL源码剖析(空间配置器)

    前言 在STL中,容器的定义中都带一个模板参数,如vector template <class T, class Alloc = alloc> class vector {...} 其中第 ...

  3. STL学习笔记:空间配置器allocator

    allocator必要接口: allocator::value_type allocator::pointer allocator::const_pointer allocator::referenc ...

  4. STL源码剖析——空间配置器Allocator#1 构造与析构

    以STL的运用角度而言,空间配置器是最不需要介绍的东西,因为它扮演的是幕后的角色,隐藏在一切容器的背后默默工作.但以STL的实现角度而言,最应该首先介绍的就是空间配置器,因为这是这是容器展开一切运作的 ...

  5. STL源码剖析——空间配置器Allocator#2 一/二级空间配置器

    上节学习了内存配置后的对象构造行为和内存释放前的对象析构行为,在这一节来学习内存的配置与释放. C++的内存配置基本操作是::operator new(),而释放基本操作是::operator del ...

  6. STL源码剖析——空间配置器Allocator#3 自由链表与内存池

    上节在学习第二级配置器时了解了第二级配置器通过内存池与自由链表来处理小区块内存的申请.但只是对其概念进行点到为止的认识,并未深入探究.这节就来学习一下自由链表的填充和内存池的内存分配机制. refil ...

  7. STL源码分析读书笔记--第二章--空间配置器(allocator)

    声明:侯捷先生的STL源码剖析第二章个人感觉讲得蛮乱的,而且跟第三章有关,建议看完第三章再看第二章,网上有人上传了一篇读书笔记,觉得这个读书笔记的内容和编排还不错,我的这篇总结基本就延续了该读书笔记的 ...

  8. STL——空间配置器(构造和析构基本工具)

    以STL的运用角度而言,空间配置器是最不需要介绍的东西,它总是隐藏在一切组件(更具体地说是指容器,container)的背后,默默工作,默默付出.但若以STL的实现角度而言,第一个需要介绍的就是空间配 ...

  9. STL 之 空间配置器(allocator)

    一.SGI 标准的空间配置器,std::allocator SGI也定义了一个符合部分标准,名为allocator的配置器,但是它自己不使用,也不建议我们使用,主要原因是效率不佳. 它只是把C++的操 ...

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

    一. 空间配置器标准接口 参见<STL源码剖析>第二章-2.1.<memory>文件. 二.具备次配置力的SGI空间配置器 1. SGI STL的配置器与众不同,也与标准规范不 ...

随机推荐

  1. C# 128位AES 加密解密 (转)

    /// AES加密 2         /// </summary> 3         /// <param name="inputdata">输入的数据 ...

  2. JS 传递对象问题,指针引用

    $(function () { var test1 = function (args) { args.name = "lcc2"; args = { name: "lcc ...

  3. 关于js中的回收机制,通俗版

    在前面的几篇文章中,我讲解过了js中的回收机制,但是对于当时的我来说,我自己对回收机制的这个概念也有些懵懵懂懂,现在对回收机制有了更深入的理解,所以特此发布此文给于总结,也好加深记忆. 如果你想学习闭 ...

  4. CentOS6部署VNC服务端

    VNC (Virtual Network Computer)是虚拟网络计算机的缩写.VNC 是在基于 UNIX 和 Linux 操作系统的免费的开源软件,远程控制能力强大,高效实用,其性能可以和 Wi ...

  5. 【转】github上值得关注的前端项目

    综合/资源 frontend-dev-bookmarks 一个巨大的前端开发资源清单.star:15000 front-end-collect 分享自己长期关注的前端开发相关的优秀网站.博客.以及活跃 ...

  6. 【转载】取消Debian系统自动锁屏

    Linux的自动锁屏功能,会在你离开屏幕的两分钟,甚至更短的时候内,将屏幕锁住,需要输入密码才能进入Linux系统. 可按下图设置,关掉Linux自动锁屏功能 System-->Preferen ...

  7. Python单元测试框架之pytest -- 断言

    对于测试来讲,不管是功能测试,自动化测试,还是单元测试.一般都会预设一个正确的预期结果,而在测试执行的过程中会得到一个实际的结果.测试的成功与否就是拿实际的结果与预期的结果进行比较.这个比的过程实际就 ...

  8. 如何单独启动wamp 中自带的MySQL

    前言:Wamp集成了Apache.MySQL和PHP环境.使用Wamp进行网站开发,是很多网站开发爱好者的选择.同时,其集成的MySQL服务,也常被用于MySQL的开发.这个时候我们只是想启动MySQ ...

  9. QCustomplot使用分享(四) QCPAbstractItem

    一.是什么 说起图,大家一下就可能想到折线图.柱状图和饼图等,但是除了这些显眼的东西以外其实还有很多东西辅助的存在着,有了这些辅助的东西图才会看起来有意义,或者说更加的真实.有说服力.这些东西都包括那 ...

  10. BZOJ3732 解析报告//LCA,最小生成树

    3732: Network 题目描述 给你N个点的无向图 (1 <= N <= 15,000),记为:1…N. 图中有M条边 (1 <= M <= 30,000) ,第j条边的 ...