侯捷 C++内存管理 第二章节 std::allocator 笔记

系列文章目录

侯捷 C++内存管理 第一章节 memory primitives 笔记
侯捷 C++内存管理 第二章节 std::allocator 笔记
侯捷 C++内存管理 第三章节 malloc/free 笔记
侯捷 C++内存管理 第四章节 loki::allocator 笔记



一、不同版本的allocator设计

1. VC6、BC5、G2.9和G4.9的allocator

这些版本下的allocator()本质上都是malloc()
在这里插入图片描述
在这些版本下,所有的容器都是直接调用allocator(),即第二个模板参数都是allocator。
在这里插入图片描述

2. G2.9的alloc流程解析

在这里插入图片描述
  原始的allocator()只维护一个内存链表,链表中每个节点的内存块大小根据创建allocator的对象来决定。现在的alloc通过free-list维护16条链表,节点的内存块大小从8byte到128byte共16种。

  内存申请过程:程序申请一块32bytes大小的空间,alloc会先通过malloc申请一块3240bytes的空间,分一块给程序,3219挂到free-list上维护为一条大小为32bytes,个数为19的链表,剩下3220交给备用空间,暂时不进行处理。若程序继续要申请一块64bytes大小的空间,则直接将刚刚剩余的3220的空间挂到free-list变为64*10的链表,并把第一个节点内的内存分配给程序。

注意点:
  1.每一个区块采用union结构,前四个字节表示为指向下一个区块的指针,好处是减少了额外的指针开销。
  2.每条链表的长度为1-20,即使空间足够,长度也不会超过20。
  3.若当前需要申请一块104bytes的空间,而备用空间只剩下80bytes,则先将备用空间的80bytes挂到#9号链表下,再进行内存申请,若空间剩余不为8的倍数,则向上补齐为8的倍数再放入链表。
  4.若当前要申请一块72bytes的空间,备用空间不够,系统内存也不够无法通过malloc()额外申请。则将80bytes的链表(即最靠近72bytes,且比72bytes大的链表)中切下一块放入备用空间,再从备用空间中切下72bytes,交给程序。若80bytes的链表也没有空间,则依次向后继续找,若找到128bytes仍然没有足够的空间,则报错内存分配失败。
  5.备用空间是通过一头一尾两个指针来界定。
在这里插入图片描述
  6.当程序将空间返回时,若大于128bytes,直接通过一级配置器返还给系统,若小于128bytes,则直接安插到free-list对应链表的头部
在这里插入图片描述
  7.若程序申请80bytes的内存空间,链表上为空,则先调用备用空间。若备用空间能分配一块以上但不足20块的内存大小,则将内存切成尽可能多的小块,将一块内存分配给程序,剩余内存块挂到链表上;若系统空间内存足够,则将一块内存分配给程序,剩余19块内存挂载到链表上,并通过指针相连。
在这里插入图片描述
  8.若程序申请80bytes的内存空间,链表上为空且备用空间不足,则free-list会调用refill()函数来填充链表,进行malloc()操作。若系统空间只能分配一块80bytes,则直接将内存分配给程序,不挂到链表上;若系统空间内存足够,则将一块内存分配给程序,剩余19块内存挂载到链表上,并通过指针相连。
在这里插入图片描述
  9.为什么当备用空间不足,且系统空间不足以申请20块内存时,要从更大的内存块链表切下一块放入备用空间,而不是向系统申请一块内存?
  因为链表上挂着的内存,本质上都是由alloc维护,如果这样做就相当于不使用alloc现有的内存而去向系统继续申请额外内存,后果是当前程序占有的内存越来越大,对于多任务系统是一种灾难。尽可能使用已经拥有的内存!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值