之前说道alloc是原G2.9版本的默认的分配器,这篇就把alloc的原理梳理梳理,顺便简单介绍下有关的内存管理。

  一般而言,我们通常习惯的内存分配操作和释放操作是这样的:

    class Foo {…};

    Foo* p = new Foo;   // 分配内存,然后构造对象

    Delete p;           // 将对象析构, 然后释放内存

  这里的内存分配操作由alloc::allocate()负责, 内存释放操作由alloc::deallocate()负责。

当我们申请的内存很小时,那么new(只是对malloc进行简单的包装)的空间便会形成一定程度的浪费,为什么这么说?我们先来看看基本的内存分配:

       

    (图片来自于侯捷老师的课程《内存管理》,侵删)

  当我们申请10个int对象时,内存分配的空间其实不是10 * 4 = 40个字节这么简单. 如图所示(调试状态下)最上边和最下边的两个cookie(用来记录分配空间的大小)4*2 = 8, 橙色的是Debug状态下申请出的空间帮助Debug,为32 + 4 = 36.而中间部分才为你要申请的10 * 4 = 40个字节,将这些数据加起来40 + 8+36 = 84,而pad那部分则是编译器进行自动补齐,将字节数调整成16的倍数,于是84 + 12 = 96.也就是说你只申请了10个int,而编译器却给你返回96个字节的空间,很神奇是不是?当然重点不是这里,想一下,如果我们只需要申请1个int呢?而上下两个cookie就占了8个字节,是不是很浪费?

  为了考虑小型区块可能造成的浪费及内存破碎问题,SGI设计了双层级分配器,第一级分配器直接使用malloc()和free()。第二级分配器则视情况采取用不同的策略,当分配空间大于128个字节时调用一级分配器,小于128字节时,便采用更复杂的内存池管理方式,也就是alloc。

为了方便管理,SGI第二级分配器会主动将任何小额区块的内存需求量上调至8的倍数(如客端要求30字节,就自动调整为32个字节),并维护16个free-lists,各自管理大小为别为8,16,24,32,40,48,56,64,72,80,88,96,104,112,120,128字节的小额区块,free-lists的示意图如下:

  (图片来自于侯捷老师的课程《内存管理》ppt,侵删)

  比如我们申请32字节的空间,然后32 / 8 = 4,即应该落在3号的位置上。alloc内部并不是一次只申请这么多空间。而是一次申请需求的40倍那么大,即40 * 32 = 1280个字节。然后一半存进内存池,另一半切分为20小块, 分一块给客户,剩下的挂在5号元素上。比如再需要申请64个字节,64 / 8 = 8,挂在7号元素上,此时内存池有上次留下的1280 / 2 = 640个字节的空间. 640 / 64 = 10块,分一块给客户,剩下的挂在7号元素上。如图:

  假如当时内存池空间不足时,则再申请 64 * 40 = 2560个字节的空间. 其中一半1280个字节的空间存内存池,剩下的另一半切20个小块,一块分客户,剩下的挂7号元素上面。

  基于这样的原理: 每次申请一大块,慢慢切割来使用,可以减小cookie的不必要的浪费。想象一下,如果申请100万个小额空间,那么省下近800万个字节的空间。也不算小数目了。可谓为了内存利用率,无所不用其极。

然而现在G4.9版本已经不将alloc设置为默认分配器了,原因呢也不清楚。 当然了,这个alloc分配器还是存在的,毕竟这么好的东西。现在它已经在G4.9版本中换了个名字:_pool_alloc(就是内存池的意思嘛),而且也将它置于__gnu_cxx命名空间中,要是我们想用它来当做容器的分配器呢,可以这么使用:

    vector<int, __gnu_cxx::_pool_alloc<int>>   vec;

  当然了alloc内存格局还是非常复杂的,这里我们只是简单了解下它的基本原理。如需了解详情,推荐《STL源码剖析》。相关知识点于第二章---空间置配器(allocator)。

简单来谈谈alloc分配器的更多相关文章

  1. 【bzoj1604】【[Usaco2008 Open]Cow Neighborhoods】简单的谈谈曼哈顿距离

    (最近p站上不去要死了) Description 了解奶牛们的人都知道,奶牛喜欢成群结队.观察约翰的N(1≤N≤100000)只奶牛,你会发现她们已经结成了几个"群".每只奶牛在吃 ...

  2. G++ 4.4.7 无法编译模板程序,Vs可以,和解?智者尾部留言,本人第一次使用vs pro,通常并且习惯在linux下写些小东西,虽然程序简单;

    vs 模板编译运行Ok \ linux g++ 4.4.7编译模板测试程序,报无法定义 template <typename or class 中的 AnyType> 类型的数据 Exam ...

  3. iOS面试题汇总

    摘要:1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 答: Object-c的类不可以多重继承;可以实现多个接口,通 ...

  4. 最全的iOS面试题及答案-转载

    1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 答: Object-c的类不可以多重继承:可以实现多个接口,通过实现 ...

  5. 李洪强iOS经典面试题124

    1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 答: Object-c的类不可以多重继承;可以实现多个接口,通过实现 ...

  6. 超全!iOS 面试题汇总

    之前看了很多面试题,感觉要不是不够就是过于冗余,于是我将网上的一些面试题进行了删减和重排,现在分享给大家.(题目来源于网络,侵删) 1. Object-c的类可以多重继承么?可以实现多个接口么?Cat ...

  7. iOS面试题及答案2015.6.7

    iOS面试题及答案     1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 答: Object-c的类不可以多重继承 ...

  8. linux设备驱动归纳总结(三):6.poll和sellct【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-61749.html linux设备驱动归纳总结(三):6.poll和sellct xxxxxxxxxx ...

  9. iOS 面试题汇总

    1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么? 答: Object-c的类不可以多重继承;可以实现多个接口,通过实现 ...

随机推荐

  1. iOS应用数据存储2-SQLite3数据库

          SQLite3 SQLite3是一款开源的嵌入式关系型数据库,可移植性好,易使用,内存开销小. SQLite3是无类型的,意味着你可以保存任何类型的数据到任意表的任意字段中. SQLite ...

  2. 日常笔记 ---- 图形学-Frenel函数材质球实现方式

    图形学-Frenel函数材质球实现方式   调个材质 大概公式 自发光= 自定义边光颜色* ((1-法线与视角方向点乘)的 自定义幂次方 ) 这个是比较简单方法   模型的法线与视角方向 角度越大 表 ...

  3. 如何垂直居中一个<img>?

    <!doctype html><html> <head> <meta charset="UTF-8"> <meta name= ...

  4. iOS运行时工具-cycript

    cycript是大神saurik开发的一个非常强大的工具,可以让开发者在命令行下和应用交互,在运行时查看和修改应用.它确实可以帮助你破解一些应用,但我觉得这个工具主要还是用来学习其他应用的设计(主要是 ...

  5. 黑马程序员:Java编程_异常

    =========== ASP.Net+Android+IOS开发..Net培训.期待与您交流!=========== 异常即对问题的描述,将问题进行对象的封装. 1. 异常体系:Throwable ...

  6. Linux平台屏幕录像工具RecordMyDesktop

    如果你把Linux桌面效果自定义得很漂亮,是不是很想录下来和其他人一起分享呢?RecordMyDesktop完全满足需要,我期待这么一个软件很久了,以前也一直没有找到合适的. 以后每次发Ubuntu的 ...

  7. 给JavaScript初学者的24条最佳实践(share)

    不错的文章,留个备份 原文链接: net.tutsplus   翻译: 伯乐在线- yanhaijing译文链接: http://blog.jobbole.com/53199/ 作为“30 HTML和 ...

  8. POJ 1990 MooFest(树状数组)

                                                                        MooFest Time Limit: 1000MS   Mem ...

  9. ios获取CELLID,LAC等信息方法

    搞了一个来月的这个东西了,还是没有完全解决问题,下面方法可以获取简单的Cell信息,方法一://CoreTelephony.h//主要就这两个结构体,其他需要的话,自己添加struct CTServe ...

  10. Python图表绘制:matplotlib绘图库入门

    matplotlib 是Python最著名的绘图库,它提供了一整套和matlab相似的命令API,十分适合交互式地行制图.而且也可以方便地将它作为绘图控件,嵌入GUI应用程序中. 它的文档相当完备,并 ...