STL源码剖析——内存空间管理

STL内存空间管理工具alloc

1.第一级配置器__malloc_alloc_template

staic void *allocate(size_t n) {
    void *result = malloc(n);//直接调用malloc
    if (0 == n) result = oom_malloc(n);
    return result;
}

static void *deallocate(void *p, size_t n) {
    free(p);
}

static void *reallocate(void *p, size_t old_size, size_t new_size) {
    void *result = realloc(p, new_size);
    if (result == 0) result = oom_realloc(p, new_size);
    return result;
}

很明显一级配置器只是简单的对C函数malloc, free, realloc的封装,当malloc, realloc向系统申请空间失败时,这两个函数反复调用用户传过来的out of memory handler处理函数,直到申请到内存为止(类似C++的set_new_handler)。如果用户并没有传递__malloc_alloc_oom_handler则抛出__THROW_BAD_ALLOC异常 。

2.第二级配置器__default_alloc_template

第二级配置器为了避免小额区块造成的内存碎片问题,采用内存池来管理内存。当请求的内存大于128bytes时转调用第一级配置器。小于等于128bytes时就从此配置器维护的内存池中分配内存。

内存池采用free_list维护空闲内存空间,free_list如下

这里写图片描述

free_list 是这些空闲链表的起始地址组成的数组,大小为16,每个链表中空闲空间的大小都是固定的,大小分别为8,16,24,32,40,48 , 56 , 64 , 72 , 80 … 128bytes。还有两个指针start_free, end_free分别指向内存池的首尾,heap_size记录已分配出去的总大小。

内存分配规则如下

1.如果申请的内存空间大于128,转调用第一级配置器
2.将申请空间的大小上调至8的倍数size,并根据size找出对应的空闲链表地址free_list[index]
3.如果free_list[index]不为空则将此地址返回,free_list[index]指向空闲链表下个节点,为空则到4
4.此时free_list[index]中没有空闲块可用,调用refill函数,重填free_list

fefill过程如下:
1.调用chunk_alloc尝试申请大小为20 * size的空间,但是不一定能申请到20 * size
2.如果只获得了size * 1大小的空间,就把此空间分配给调用者,free_list无新节点,否则,将分配的空间的第一块返回给调用者,其余空间串接到free_list[index]维护的空闲链表上

chunk_alloc过程:
1.如果内存池空间(end_free - start_free)够 size * n(n默认为20),则将空间分配出去,更新start_free,否则到2
2.内存池空间不够size * n,但是大于size,则分配 (end_free - start_free) / size个size大小的空间,更新start_free,否则到3
3.此时说明内存池剩余空间一个size大小的区块都不能提供,如果内存池中还有剩余空间(肯定小于size)则将此空间连接到到对应的空闲链表中
4.调用malloc申请 2 * size * n + ROUND_UP(heap_size >> 4)大小的空间,如果申请成功,更新start_free, end_free, heap_size,并重新调用chunk_alloc(更新n,即实际分配的区块数),否则到5
5.此时malloc也申请失败,则遍历free_list[index]到free_list[15],只要有一个空闲,就释放出该链中的一个区块,更新start_free,end_free分别指向此块的首尾,再重新调用chunk_alloc(更新n,即实际分配的区块数)

内存释放规则如下

函数原型static void deallocate(void *p, size_t n);
如果n > 128则调用第一级配置器直接free,否则调整free_list,回收此区块,将此区块添加到对应的free_list[index]维护的空闲链表中

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
当读者有一定c/c++基础 推荐的阅读顺序: level 1 从<>开始,短小精悍,可以对c++能进一步了解其特性 以<>作字典和课外读物,因为太厚不可能一口气看完 level 2 然后从<>开始转职,这是圣经,请遵守10诫,要经常看,没事就拿来翻翻 接着是<>,个人认为Herb Sutter主席大人的语言表达能力不及Scott Meyers总是在教育第一线的好 顺下来就是<>和<>,请熟读并牢记各条款 当你读到这里,应该会有一股升级的冲动了 level 3 <>看过后如一缕清风扫去一直以来你对语言的疑惑,你终于能明白compiler到底都背着你做了些什么了,这本书要细细回味,比较难啃,最好反复看几遍,加深印象 看完上一本之后,这本<>会重演一次当年C++他爹在设计整个语言过程中的历程 level 4 <>是stl的字典,要什么都可以查得到 学c++不能不学stl,那么首先是<>,它和圣经一样是你日常行为的规范 <>让你从oo向gp转变 光用不行,我们还有必要了解stl的工作原理,那么<>会解决你所有的困惑 level 5 对于c++无非是oo和gp,想进一步提升oo,<>是一本主席这么多年的经验之谈,是很长esp的 一位stl高手是不能不去了解template的,<>是一本百科全书,足够你看完后对于gp游刃有余 <>是太过聪明的人写给明眼人看的 好书有很多,不能一一列举 以上我的读书经历,供各位参考。接下来的无非就是打怪练级,多听多写多看;boost、stl、loki这些都是利器,斩妖除魔,奉劝各位别再土法练钢了。 at last,无他,唯手熟尔。 忘了一本《thinking in C++》 也是经典系列之一 <>这本圣经的作者Scott Meyesr在给<>序言的时候高度的赞赏了Andrei同志的工作:C++社群对template的理解即将经历一次巨大的变化,我对它所说的任何事情,也许很快就会被认为是陈旧的、肤浅的、甚至是完全错的。 就我所知,template的世界还在变化,速度之快就像我1995年回避写它的时候一样。从发展的速度来看,我可能永远不会写有关template的技术书籍。幸运的是一些人比我勇敢,Andrei就是这样一位先锋。我想你会从此书得到很多收获。我自己就得到了很多——Scott Meyers September2000。 并且,Scott Meyers 在最近的Top5系列文章中,评价C++历史里面最重要5本书中、把Modern C++ Design列入其中,另外四本是它自己的effective c++、以及C++ Programming Language、甚至包括《设计模式》和《C++标准文档》。 显然,Scott Meyers已经作为一个顶尖大师的角度承认了<>的价值。 并且调侃地说,可以把是否使用其中模板方法定义为,现代C++使用者和非现代C++使用者,并且检讨了自己在早期版本Effective对模板的忽视,最后重申在新版本Effective第七章节加入大量对模板程序设计的段落,作为对这次失误的补偿。 并且,在这里要明确的是<>并不是一本泛型编成的书,也不是一本模板手册。其中提出了基于策略的设计方法,有计划和目的的使用了模板、面向对象和设计模式。虽然Andrei本人对模板的研究世界无人能敌,但对其他领域的作为也令人赞叹。 任何做游戏的人都不能忽视OpenAL把,你在开发者的名单里能看到Loki的名字:) 最近很忙,无时间写文章,小奉献一下书籍下载地址。虽然经过验证,但是不感肯定各位一定能下: 中文 http://www.itepub.net/html/ebookcn/2006/0523/40146.html 英文 http://dl.njfiw.gov.cn/books/C/Essential%20C

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值