本文章由vector03原创, 转载请注明出处.

邮箱地址: mmzsmm@163.com, 欢迎来信讨论.

3.4 sys_alloc

sys_alloc是dlmalloc中向系统获取内存的主要接口.
因为涉及到mmap, top-most segment, top chunk的交互,
相对要更复杂. 我们相同先介绍主要分配算法,
再具体分析子函数.

3.4.1 核心算法

基本上sys_alloc分为四个步骤,

1. 首先检查请求大小nb是否超出mmap_threshold的阈值.
假设是, 则放弃由分配器管理,
直接在mmap区开辟,
原因前面说过, 不再赘述.

2. 依据mspace设定及当前top space的使用情况,
向系统申请一块适当的内存.

Dlmalloc依照以下的顺序由主到次开辟,

第一, 假设同意MORECORE,
则优先通过MORECORE开辟连续内存空间.

连续空间开辟又分为例如以下几种情况,

若当前mspace处于诞生阶段,
则直接开辟nb + SYS_ALLOC_PADDING大小的空间.

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmVjdG9yMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">

若当前mspace已存在top,
则部分空间可利用top, 剩余nb – m->topsize + SYS_ALLOC_PADDING大小的空间向系统申请.

若MORECORE返回成功,
但空间不连续, 则会尝试扩展空间esize大小以满足分配需求.
假设空间扩展失败, 则反向MORECORE将之前申请的空间归还给系统.

第二, 假设上一步申请失败,
或不同意MORECORE, 则通过MMAP申请.
注意, 这里的MMAP同sys alloc步骤1的mmap是两码事.
这一步申请的结果是要归入mspace空间的.

第三, 倘若前两步都失败,
且同意非连续(noncontiguous)MORECORE, 则尝试直接在system heap上分配非连续空间.
这有些类似第一步中的扩展空间, 差别是此时已经明白top space不连续,
直接申请目标大小.

3. 依据申请成功的地址与原top space的关系,
对连续空间合并. 假设不能合并,
则新开区段. 申请的地址和大小保存在tbase和tsize暂时变量里.

当中, 区段合并又分为两种.
若tbase与top-most区段末尾相毗邻,
则从后面合并. 这样的情况适用于大部分MORECORE以及小部分MMAP申请到的空间.

若tbase与top-most区段開始相毗邻,
则从前面合并. 这样的情况出现的比較少,
多在MMAP时产生, MORECORE尽管也可能出现该情况,
相对就更少.

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmVjdG9yMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">

4. 最后从已扩展的top space中划分chunk返回给用户.
这样就完毕了sys_alloc的所有流程.

具体代码凝视例如以下,

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmVjdG9yMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">

这个代码基本上就是本小节開始时介绍的流程,
相信看懂了前面的算法说明, 这里自然没有什么难度.
须要说明的仅有两点,

一个就是在Line4064和Line4065出现的推断,
先对nb做padding计算得到asize,
再推断其是否小于等于nb. 这里就是溢出检測,
对于两个无符号整数的加法, 这是比較便捷的检验方法.
类似的代码在dlmalloc中到处都是.

还有一个參考Line4108,
这里相同是溢出检測. 由于MORECORE的入參在dlmalloc中被觉得是有符号的.
而HALF_MAX_SIZE_T是size_t的一半,
以此来推断ssize是否溢出.

3.4.2 mmap_alloc

当nb大于mmap_threshold时,
会调用该函数直接进行mmap分配.
与sys_alloc通过其它途径申请的差别在于, dlmalloc对这类空间倾向于不长期持有,
也不纳入不论什么分箱或区段中. 能够觉得它们是脱离dlmalloc管理的孤立内存区域.

既然是孤立内存,
首尾就不会有毗邻的chunk, 但直接mmap出来的payload地址未必是对齐的,
因此在对齐后会产生内部碎片. dlmalloc就将这些碎片伪装成一个chunk.
这样, 当用户释放这片内存时,
能够依据记录在prev_foot中的size信息找到当初mmap出来的首地址.

上图中, mmap分配的原始地址是mm,
经过对齐后的地址是p. dlmalloc将前面的对齐部分伪装成一个free chunk,
长度记录在p->prev_foot中.
当释放时, 就能够依据payload指针又一次计算出mm的地址.
在结尾, 有长度为MMAP_FOOT_PAD的一段区域,
用来放置fake next chunk. 也就是保存magic以及fencepost.

代码凝视例如以下,

3.4.3 prepend_alloc

在3.4.1小节中介绍了从系统申请的扩展内存会依据其首地址和旧区段之间的位置关系做合并.
倘若append到区段后面,
申请内存是比較简单的, 由于扩展地址会直接补充到top中,
仅仅需分割top就可以.
但假设prepend到前面情况就相对复杂了,
由于从原区段base到top之间的情况不明,
所以必须分情况讨论. 而prepend_alloc函数就是为此而写的.

该函数会在一開始将分配请求从扩展空间中分割出来,
剩余工作就是依据不同情况对remainder做对应处理,

1. 假设旧区段base与top是同一个地址,
直接移动top指针,
将remainder吸收到top中.

2. 假设旧区段base与dv是同一地址,
则扩充dv的范围.

3. 若旧区段開始是普通的free chunk,
则移动oldfirst指针,
将remainder和free chunk合并.

4. 若旧区段開始是inused chunk,
则将remainder插入回分箱.

代码凝视例如以下,

3.4.4 add_segment

对于无法合并的扩展内存区域, dlmalloc最后会将它们作为新的segment插入.

创建新segment依照例如以下步骤进行,

1. 首先,
依据top, 查找到当前top-most区段,
而且定位出在其结尾的隐藏chunk.

2. 将top又一次初始化为新的segment的基址.

3. 将mstate中保存的旧top-most区段信息push到旧区段的隐藏chunk里.
并将新区段信息记录在mstate中.

4. 旧区段末尾写入一连串fenceposts.

5. 若旧区段剩余的top可用,
则将旧top又一次插入分箱系统中.

源代码凝视例如以下,

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmVjdG9yMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">

Line4016是top初始化函数,
该函数基本仅仅是简单的信息记录, 并在末尾伪装隐藏chunk,
代码例如以下,

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdmVjdG9yMDM=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center">

dlmalloc 2.8.6 源代码具体解释(6)的更多相关文章

  1. dlmalloc 2.8.6 源代码具体解释(5)

    本文章由vector03原创, 转载请注明出处. 邮箱地址: mmzsmm@163.com, 欢迎来信讨论.     3. 分配及实现 本章节介绍dlmalloc的分配算法和实现.由于存在多mspac ...

  2. Spring IOC源代码具体解释之容器初始化

    Spring IOC源代码具体解释之容器初始化 上篇介绍了Spring IOC的大致体系类图,先来看一段简短的代码,使用IOC比較典型的代码 ClassPathResource res = new C ...

  3. Spring IOC源代码具体解释之容器依赖注入

    Spring IOC源代码具体解释之容器依赖注入 上一篇博客中介绍了IOC容器的初始化.通过源代码分析大致了解了IOC容器初始化的一些知识.先简单回想下上篇的内容 加载bean定义文件的过程.这个过程 ...

  4. Spring IOC源代码具体解释之整体结构

    Spring ICO具体解释之整体结构 IOC介绍 IOC, spring的核心.贯穿Spring始终.直观的来说.就是由spring来负责控制对象的生命周期和对象间的关系,将对象之间的关系抽象出来. ...

  5. MQTT---HiveMQ源代码具体解释(四)插件载入

    源博客地址:http://blog.csdn.net/pipinet123 MQTT交流群:221405150 实现功能 将全部放在plugins文件夹下的全部符合plugin编写规范的plugin ...

  6. MQTT---HiveMQ源代码具体解释(一)概览

    源博客地址:http://blog.csdn.net/pipinet123 MQTT交流群:221405150 面向群体 想自己实现MQTT Broker的朋友 对现有开源的MQTT Broker或多 ...

  7. Android MediaScannerJNI源代码具体解释

    1.简单介绍 MediaScannerJNI的在MediaScanner中的地位可參考 Android MediaScanner 总纲 MediaScanner JNI文件名称: android_me ...

  8. MQTT---HiveMQ源代码具体解释(十八)Cluster-kryo与Serializer

    源博客地址:http://blog.csdn.net/pipinet123 MQTT交流群:221405150 既然是Cluster,node之间肯定是须要交互的,那么肯定是须要序列化和反序列化.Hi ...

  9. MQTT---HiveMQ源代码具体解释(七)Netty-SSL/NoSSL

    源博客地址:http://blog.csdn.net/pipinet123 MQTT交流群:221405150 实现功能 依据用户配置的不同的Listener(TcpListener.TlsTcpLi ...

随机推荐

  1. dell服务器各类raid 和磁盘在阵列卡上的实验

    听很多人说,做好阵列的硬盘从阵列上移除后,重新从硬盘导入阵列信息的时候不能打乱位置,昨天用两台Dell R710,四块sas 300G HP硬盘做实验,实验步骤如下: 一.dell R710首先用三块 ...

  2. HTC one/M7电信802d 毒蛇ViperOne2.1.0/高级毒蛇工具/完美root,精简/更多自定义,稳定,流畅ROM

    ROM版本 HTC One/M7 802d ROM作者 雪狼团队·大盛 http://weibo.com/DaShengdd Android版本 Android 4.2.2 创建日期 2013.09. ...

  3. cisco san交换机配置

    1.配置交换机的管理地址switch(config)# interface mgmt 0 switch(config-if)# ip adress 192.168.100.108 255.255.25 ...

  4. Android四个多线程分析:MessageQueue实现

    Android四个多线程分析:MessageQueue的实现 罗朝辉 (http://blog.csdn.net/kesalin) CC 许可,转载请注明出处 在前面两篇文章<Android多线 ...

  5. 从零開始学android&lt;ImageSwitcher图片切换组件.二十六.&gt;

    ImageSwitcher组件的主要功能是完毕图片的切换显示,比如用户在进行图片浏览的时候.能够通过button点击一张张的切换显示的图片,并且使用ImageSwitcher组件在每次切换的时候也能够 ...

  6. UNIX网络编程卷1 server程序设计范式7 预先创建线程,以相互排斥锁上锁方式保护accept

    本文为senlie原创.转载请保留此地址:http://blog.csdn.net/zhengsenlie 1.预先创建一个线程池.并让每一个线程各自调用 accept 2.用相互排斥锁代替让每一个线 ...

  7. Callable 获取线程返回值

    allable与 Future 两功能是Java在兴许版本号中为了适应多并法才增加的,Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其它 ...

  8. poj 2309 BST 使用树阵lowbit

    假设领悟了树阵lowbit,这个问题很简单,底部是奇数,使用lowbit(x)寻找x父亲,然后x父亲-1是的最大数量 至于lowbit问题是如何计算,寻找x父亲,事实上x+2^x二进制结束0的数量. ...

  9. 当执行游戏0xc000007b错误的解决方法

    如图,这个错误使无数玩家烦恼. 出现这个错误,可能是硬件的问题,也可能是软件的问题.可是,因为硬件引起该问题的概率非常小,而且除了更换硬件之外没有更好的解决方法,因此本文将具体介绍怎样通过软件解决此问 ...

  10. 朴素UNIX它-Linux CFS注视

    该系列产品,被称为纯UNIX,但它也包含各种类别UNIX该系统的细节,自从完成我多年的学习笔记本系列文章,分析了各种UNIX,类UNIX思想和情感的实现. 这篇文章是比较短.只是分析Linux CFS ...