dlmalloc 2.8.6 源码详解(7)

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

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

 

4. 释放与实现

释放过程相对分配就简单多了, 基本着重在chunk合并, top裁剪, segment释放上. dlmalloc中合并是减少外部碎片最有效的方法了.

4.1 dlfree

释放的主要过程就是根据用户传入的payload, 找到chunk指针, 然后分别检查前一个和后一个chunk是否可以合并. 这里唯一需要注意的就是与dvtop这些特殊chunk的交互.

基本流程如下,

1. 通过用户传入的mem指针计算出chunk指针p. 如果FOOTERS打开, 则通过magic计算出其所属的mspace指针, 并进行校验.

2. p是通过direct mmap生成的, 则还原其头尾的fake chunk后直接munmap释放并结束. 详细内容请参考3.4.2小节的说明.

3. pprev chunk也是free chunk则将pprev合并. prev同时又是dv, 则还需要考虑pnext chunk. 假如nextinused chunk, 则直接将合并后的p替换为新的dv并返回, 否则进入下一步.

4. pnext chunk也是空闲的, 则又分为三种情况,

                   a.      next是普通的free chunk, p进行合并. 如果p同时是dv, 则更新dv.

                   b.      next同时是top, 则与p合并后更新topp. 如果p同时又是dv, 则取消当前记录的dv(相当于dvtop吞并了). top已经超出trim阈值, 则执行sys_trim.

                   c.      next同时是dv, 则与p合并后更新dvp.

5. p是经历前面步骤的普通chunk, 则将更新后的p重新插入分箱系统. 如果realse_check满足, 则检查并回收当前mspace下所有的free segment.

代码注释如下,


 

 

4.2 sys_trim

dlmalloc在执行free请求时, 会检测当前top剩余空间是否超出trim_check规定的阈值. 如果是就会尝试收缩当前的top空间. 默认情况下, dlmalloc会保留一个粒度(granularity)大小的空间, 剩余的都将归还给系统, 可以传入参数pad指定额外的剩余空间(多数情况下是0). 另外, 由于top所在区段有可能位于heap区或mmap, 因此也会有不同的收缩方式. 对于heap区的top空间, 采取反向MORECORE的方式, 而对于mmap区的, 则先尝试用mremap进行收缩, 如果失败则使用mumap释放掉. 假设遇到trim失败的情况, dlmalloc就会自动关闭auto-trimming功能.

源码注释如下,


 

 

4.3 release_unused_segments

尽管有auto-trimming压缩top空间, 但多数情况下, 只依靠这种方法是无法满足内存释放需求的. 尤其是当外部碎片导致top不连续的情况下, auto-trimming可能相当一段时间无法触发. 此时, dlmalloc就转而寻找内部可回收的空闲段. 由于查找空闲段是一个耗时操作, 且出现的频率较低, 所以实际上按照一个周期来进行此操作. 当周期计数为0, 就调用release_unused_segments.

判断一个区段是否空闲也比较简单, 因为空闲chunk合并的原因, 若当前段的第一个chunk为空闲, 且其大小覆盖整个区段除隐藏区域的全部范围, 就可以判定该区段为空闲段. 接下来只要unlink空闲chunk, munmap该区段即可. 源码注释如下,

 

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
dlmalloc是目前一个十分流行的内存分配器,其由Doug Lea(主页为http://gee.cs.oswego.edu/)从1987年开始编写,到目前为止,最新版本为2.8.3(可以从ftp://g.oswego.edu/pub/misc/malloc.c获取),由于其高效率等特点被广泛的使用(比如一些linux系统等用的就是dlmalloc或其变形,比如ptmalloc,主页为http://www.malloc.de/en/index.html)和研究(各位可以搜索关键字“GCspy”)。 dlmalloc的实现只有一个源文件(还有一个头文件),大概5000行,其内注释占了大量篇幅,由于有这么多注释存在的情况下,表面上看上去很容易懂,的确如此,在不追求细节的情况,对其大致思想的确很容易了解(没错,就只是了解而已),但是dlmalloc作为一个高品质的佳作,实现上使用了非常多的技巧,在实现细节上不花费一定的精力是没有办法深入理解其为什么这么做,这么做的好处在哪,只有当真正读懂后回味起来才发现它是如此美妙。 lenky0401个人博客将陆续推出对dlmalloc的解析(针对Doug Lea Malloc的最新版Version 2.8.3,未做说明的情况下以32位平台,8字节对齐作为假定平台环境设置考虑),由于个人水平有限,因此也不能完全保证对dlmalloc的所有理解都准备无误, 但是所有内容均出自个人的理解而并非存心妄自揣测来愚人耳目,所以如果读者发现其中有什么错误,请勿见怪,如果可以则请来信告之,并欢迎来信讨论(lenky0401@163.com)。 这一系列文章是lenky0401在看完dlmalloc的大部分代码后的再总结,不能保证对dlmalloc的整体完全把握,贴出这些只是希望可以提前收到对此有研究的网友的指点,以便在最后对这一系列文章整理而形成的PDF文档中错误能少一些。至于对于现在贴出来的内容中包含的错误给大家造成的不便提前说声抱歉。:) 描述的内容不会包含dlmalloc全部代码,但会将这其中涉及到的一些技巧尽量讲出,我相信对dlmalloc源代码不感兴趣的朋友也可以学到这些独立的技巧而使用在自己的编程实践中。:) 最后,转载请保留本博客地址连接[http://lenky0401.cublog.cn],谢谢。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值