dlmalloc 2.8.6 源码详解(7)

dlmalloc-2.6.6源码分析 <br /> <br /><br /><br /> <br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br /><br />目    录<br /><br />1.Doug Lea malloc简介2<br />2.边界标记3<br />3.分箱管理7<br />4.内存分配相关函数14<br />4.1函数mALLOc( )14<br />4.2函数malloc_update_mallinfo( )22<br />5.内存回收相关函数 阅读详情

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

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

 

4. 释放与实现

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

4.1 dlfree

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

基本流程如下,

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

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

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

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

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

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

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

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该区段即可. 源码注释如下,

 

dlmalloc源码解析 从源码级别详细介绍dlmalloc内存管理思想,尤其针对算法和代码技巧角度剖析dlmalloc 立即下载

相关推荐

dlmalloc说明及代码

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],谢谢。

dlmalloc源码分析

我们写过很多C程序了,经常会分配内存。记得刚学C语言时老师说过,可以向两个地方申请内存:一个是栈、一个是堆。小块内存向栈申请,函数调用结束后程序会自动释放内存。大块内存向堆申请,记得一定要自己释放,否则会造成内存泄漏。向堆申请内存直接调用malloc()就可以了,参数是你申请的内存量。释放内存时直接调用free()就可以了,参数是内存块指针。         看似平静的海面,海底则波涛汹涌。当时

houzengjiang的专栏 3706

libdlmalloc-2.8.5.tar.bz2

libdlmalloc-2.8.5.tar.bz2

dlmalloc 2.8.6 源码详解(3)

本文章由vector03原创, 转载至 [vector03](https://blog.csdn.net/vector03/article/details/41008671)经过右移并与掩码计算的目的其实就是为了获得最高有效位的下一位。内存分配器设计中需要解决的两个重要问题就是空间和时间的矛盾。而后半部分一连串的计算其实就是判断是落在左边还是右边的分箱。的任意子树中根节点与其左右子树内的节点都没有明确的排序关系。号分箱则分别负责[2^9, 2^9+2^8)号分箱则负责[2^8+2^7, 2^9)

firebuffer的专栏 306

Linux磁盘扩容实战:用parted命令无损扩展/data分区(附常见报错解决方案)

本文详细介绍了在Linux生产环境中使用parted命令对已挂载的/data分区进行在线磁盘扩容的完整实战流程。通过风险评估、状态检查、parted工具深度解析及实战演练,指导用户安全完成动态扩容,并提供了常见报错如'Partition is being used'、MBR 2TB限制等的解决方案,确保业务不中断、数据不丢失。

weixin_29207439的博客 297

ptrade从零开始学习量化交易第166期【ptrade量化策略研究参考--三个因子挖掘思路】

三个因子挖掘思路

GJ57017_wx的博客 1250

内存分配器dlmalloc 2.8.3源码浅析

目    录 1. 本文档介绍 1 2.边界标记法 2 3. 分箱式内存管理 6 4. 核心结构体malloc_state 13 5. 内存分配相关函数 16 5.1 函数dlmalloc 16 5.2 函数tmalloc_small 25 5.3 函数tmalloc_large 27 5.4 函数sys_alloc 32 5.5 函数mmap_alloc 39 6. 内存回

larryliuqing的专栏-xxx 7408

内核工作FAST‘25 Artifact Evaluation流程记录

在我们的paper中,复现需要用到傲腾持久化内存,因此,需要AE Reviewer访问到内网服务器中。我们的思路是购买云服务器,将其作为跳板机,内网服务器通过SSH反向代理与公网服务器建立隧道,AE Reviewer通过隧道访问内网服务器。我们在AE过程中使用。然后,把一切复现需要的代码环境,在chroot里面配置完成。

不定期更新系统使用、编程小技巧,哔哩哔哩账号:https://space.bilibili.com/399455629,欢迎关注 1215

dlmalloc 2.8.6 源码详解—[3]核心数据结构malloc_state

转载自:vector032.3 区段(segment)在dlmalloc的内部结构中,除了基础的chunk外,还存在一种粒度更粗的结构,称为区段(segment).之所以需要额外引入这种数据结构是为了提升对非连续内存的管理能力. dlmalloc将连续内存划分到一个segment中管理,而段与段之间则是不连续的,所有的段都由一个mspace统一去管理.如果用户程序创建了多个mspace,这些mspa

杏林小轩 2938

思岚A1 上手教程

前言 寒假在家闲着也是闲着,索性就向是实验室借了一个思岚 A1激光雷达,来进一步完成自己的实验室实习项目。经过一个月在Linux上和ROS上的摸爬滚打,我已经对机器人开发和SLAM有了初步了解,现在就写个上手教程吧(以防自己以后忘了)。 Basic Support 硬件 一台电脑 思岚 A1激光雷达 软件 安装Virtual Box虚拟机 在虚拟机安装Ubuntu 16操作系统 在Ubuntu 16搭建ROS kinetic 简要步骤 1.现在w..

ajxdhe的博客 6390

工业数据采集实战:用open62541库读写PLC的OPC UA节点(避坑指南)

本文详细介绍了如何使用open62541库实现工业PLC的OPC UA节点数据采集,涵盖环境搭建、节点读写优化及生产环境故障排查。通过订阅模式和多节点读写技术,显著提升数据采集效率与稳定性,适用于智能制造和工业物联网场景。

weixin_30598225的博客 400

dlmalloc 2.8.6 源码详解—[4]分配及实现

转载自:vector033 分配及实现本章节介绍dlmalloc的分配算法和实现.由于存在多mspace的情况, dlmalloc使用了两套API.一套对应默认的mspace,以dl前缀开头,如dlmalloc, dlrealloc等.如果创建了自定义的mspace,则使用mspace开头的API,如mspace_malloc, mspace_realloc等.但两套API在基础算法上是一致的.我们

杏林小轩 1569

公文派2025:免费社区版重大安装更新!

距离上一次更新已经过去了将近一年的时间,今天我们带来了全新的免费2025社区版,该版本也是目前最新的版本,无需授权即可使用所有的功能。

似最初 1964

dlmalloc 2.8.6 源码详解(1)

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

vector03的专栏 9367

BIOS更新后PIN不可用怎么办?从原理到实操的完整修复指南

在计算机维护中,BIOS更新是常见的固件升级操作,但其引发的登录异常却常让用户措手不及。Windows Hello PIN并非传统密码,它通过TPM芯片与设备启动环境(PCR状态)强绑定,一旦主板固件或安全启动配置改变,TPM便会拒绝释放密钥,导致“由于此设备上的更改,你的PIN不再可用”。理解这一原理后,恢复路径清晰可控:优先尝试密码登录,或通过WinRE替换utilman.exe创建临时管理员,必要时还需处理BitLocker恢复密钥。本文面向系统维护与数据安全场景,系统梳理PIN失效的恢复流程与避坑方

weixin_31364787的博客 384

基于STM32L4XX、HAL库的AD7124模数转换器ADC驱动程序设计

/ 检查ID是否正确 (AD7124-4/AD7124-8有不同的ID)// 转换为电压值 (假设使用内部2.5V基准)// 构造读命令: 1(R/W) + 1(0) + 6(寄存器地址)// 构造写命令: 0(R/W) + 1(0) + 6(寄存器地址).config = 0, // 使用配置0。内置可编程增益放大器(PGA):1-128倍。// 读取ADC数据。// 读取当前ADC控制寄存器。// 检查数据是否就绪。// 写回ADC控制寄存器。// 初始化AD7124。

zhusl6688的博客 521

dlmalloc 2.8.6 源码详解(5)

本文章由vector03原创, 转载至[vector03](https://blog.csdn.net/vector03/article/details/41114611).首先在分配请求对应大小的分箱以及更大一级分箱中查找。如果没有则扩大范围在大于目标值的最小子树中搜索。的原因是最高有效和次高有效位用于计算分箱号。不这样写的原因可能是尽量减少各个平台的区别。本质上都是本着物尽其用的思想来挑选合适的。对多线程条件下的分配设计的还是比较简陋的。子树是当前分箱中大于目标值的最小子树。

firebuffer的专栏 225

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

dlmalloc 2.8.6 源码详解(6)

本文章由vector03原创, 转载至[vector03](https://blog.csdn.net/vector03/article/details/41205355).小节中介绍了从系统申请的扩展内存会根据其首地址和旧区段之间的位置关系做合并。该函数会在一开始将分配请求从扩展空间中切割出来。这个代码基本上就是本小节开始时介绍的流程。这有些类似第一步中的扩展空间。中向系统获取内存的主要接口。将之前申请的空间归还给系统。对于无法合并的扩展内存区域。向系统申请一块适当的内存。这一步申请的结果是要归入。

firebuffer的专栏 261

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

dlmalloc 2.8.6 源码详解(2)

本文章由vector03原创, 转载至[vector03](https://blog.csdn.net/vector03/article/details/40979181)这就保证了两种类型在基础结构上具有较好的兼容性。这个结构体中间填充多长的内容是没法确定的。的作用是将连续内存划分为一段段小的区块。将用户请求的内存值转化成实际的内部大小。与前者的区别在于管理上使用不同的结构。源码中定义了大量的宏来对其进行操作。的源码中有一幅用字符画成的示意图。在上一节的图中并没有画出对应的。

firebuffer的专栏 176

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

dlmalloc 2.8.6 源码详解(4)

之所以需要额外引入这种数据结构是为了提升对非连续内存的管理能力。对某一大小内存的分配和释放都趋向于在一段时间里连续执行。从系统获取一定量内存后按照用户程序需求返回不同大小的。内存空间的整体分配能力和分配速度也获得了明显提升。这样其他人再来买同牌子的烟就继续从拆开的那条里取。如此全能的原因在于它位于内存空间的最顶端。其内部记录了关于内存分配的所有关键数据。这里使用的技术类似于操作系统中的就绪表。的初始状态与编译器的相关功能宏开关有关。小块内存如同人体血液中的坏胆固醇一样。此调用会根据传入的基址建立一个新的。

firebuffer的专栏 176
上一篇: dlmalloc 2.8.6 源码详解(6)
下一篇: Inside of Jemalloc
vector03
博客等级 码龄16年 62粉丝 16原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值