malloc的底层实现(ptmalloc)

ptmalloc源码剖析 ptmalloc内存管理器 ptmalloc是glibc默认的内存管理器。我们常用的malloc和free就是由ptmalloc内存管理器提供的基础内存分配函数。ptmalloc有点像我们自己写的内存池,当我们通过malloc或者free函数来申请和释放内存的时候,ptmalloc会将这些内存管理起来,并且通过一些策略来判断是否需要回收给操作系统。这样做的最大好处就是:让用户申请内存和释放内存的... 阅读详情
AI摘要

ptmalloc是C运行时库用于内存管理的一种实现,它采用内存池的方式提高内存分配和回收效率。内存布局分为栈、堆和mmap映射区域。malloc主要通过brk和mmap函数进行内存分配,使用主分配区和非主分配区解决多线程锁竞争,通过chunk内存块管理内存。malloc流程包括fast bins、unsorted bins、small bins、large bins和top chunk的查找和分配,而内存回收涉及fast bins、unsorted bins和top chunk的合并及mmap内存的释放。

前言

  本文主要介绍了ptmalloc对于内存分配的管理。结合网上的一些文章和个人的理解,对ptmalloc的实现原理做一些总结。

内存布局

  介绍ptmalloc之前,我们先了解一下内存布局,以x86的32位系统为例:
  这里写图片描述
  从上图可以看到,栈至顶向下扩展,堆至底向上扩展, mmap 映射区域至顶向下扩展。 mmap 映射区域和堆相对扩展,直至耗尽虚拟地址空间中的剩余区域,这种结构便于 C 运行时库使用 mmap 映射区域和堆进行内存分配。

brk(sbrk)和mmap函数

  首先,linux系统向用户提供申请的内存有brk(sbrk)和mmap函数。下面我们先来了解一下这几个函数。

brk() 和 sbrk()

#include <unistd.h>
int brk( const void *addr )
void* sbrk ( intptr_t incr );

两者的作用是扩展heap的上界brk
Brk()的参数设置为新的brk上界地址,成功返回1,失败返回0;
Sbrk()的参数为申请内存的大小,返回heap新的上界brk的地址

mmap()

#include <sys/mman.h>
void *mmap(void *addr, size\_t length, int prot, int flags, int fd, off\_t offset);
int munmap(void *addr, size_t length);

Mmap的第一种用法是映射此盘文件到内存中;第二种用法是匿名映射,不映射磁盘文件,而向映射区申请一块内存。
Malloc使用的是mmap的第二种用法(匿名映射)。
Munmap函数用于释放内存。

主分配区和非主分配区

Allocate的内存分配器中,为了解决多线程锁争夺问题,分为主分配区main_area和非主分配区no_main_area。
 1. 主分配区和非主分配区形成一个环形链表进行管理。
 2. 每一个分配区利用互斥锁使线程对于该分配区的访问互斥。
 3. 每个进程只有一个主分配区,也可以允许有多个非主分配区。
 4. ptmalloc根据系统对分配区的争用动态增加分配区的大小,分配区的数量一旦增加,则不会减少。
 5. 主分配区可以使用brk和mmap来分配,而非主分配区只能使用mmap来映射内存块
 6. 申请小内存时会产生很多内存碎片,ptmalloc在整理时也需要对分配区做加锁操作。

当一个线程需要使用malloc分配内存的时候,会先查看该线程的私有变量中是否已经存在一个分配区。若是存在。会尝试对其进行加锁操作。若是加锁成功,就在使用该分配区分配内存,若是失败,就会遍历循环链表中获取一个未加锁的分配区。若是整个链表中都没有未加锁的分配区,则malloc会开辟一个新的分配区,将其加入全局的循环链表并加锁,然后使用该分配区进行内存分配。当释放这块内存时,同样会先获取待释放内存块所在的分配区的锁。若是有其他线程正在使用该分配区,则必须等待其他线程释放该分配区互斥锁之后才能进行释放内存的操作。

Malloc实现原理:

  因为brk、sbrk、mmap都属于系统调用,若每次申请内存,都调用这三个,那么每次都会产生系统调用,影响性能;其次,这样申请的内存容易产生碎片,因为堆是从低地址到高地址,如果高地址的内存没有被释放,低地址的内存就不能被回收。
  
  所以malloc采用的是内存池的管理方式(ptmalloc),Ptmalloc 采用边界标记法将内存划分成很多块,从而对内存的分配与回收进行管理。为了内存分配函数malloc的高效性,ptmalloc会预先向操作系统申请一块内存供用户使用,当我们申请和释放内存的时候,ptmalloc会将这些内存管理起来,并通过一些策略来判断是否将其回收给操作系统。这样做的最大好处就是,使用户申请和释放内存的时候更加高效,避免产生过多的内存碎片。

chunk 内存块的基本组织单元

在 ptmalloc 的实现源码中定义结构体 mallo

ptmalloc、tcmalloc与jemalloc对比分析 ptmalloc、tcmalloc与jemalloc对比分析。 阅读详情

相关推荐

malloc 函数详解

malloc函数和free函数详解 引言:为什么使用动态内存分配 当你声明数组时,你必须用一个编译时常量指定数组的长度。但是,数组的长度常常在运行时才知道,这是由于它所需要的内存空间取决于输入数据。例如,一个用于计算学生等级和平均分的程序可能需要存储一个班...

tyustli 7万+

浅析malloc的底层实现原理(ptmalloc)

内存布局 、brk(sbrk)与mmap函数 、内存管理的一般方法、ptmalloc简介 、内存管理数据结构概述 、内存分配、回收概述

ZY-JIMMY 4529

[系统安全] malloc的底层原理—ptmalloc堆概述

当需要分配一个 small chunk,但在 small bins 中找不到合适 的 chunk,如果 last remainder chunk 的大小大于所需的 small chunk 大小,last remainder chunk 被分裂成两个 chunk,其中一个 chunk 返回给用户,另一个 chunk 变成新的 last remainder chuk。内存分配时,先在fast bin中找是否有满足条件的chunk,没有的话再去small bins中找。

H4ppyD0g的博客 1342

为什么需要知识图谱?什么是知识图谱?——KG的前世今生

我的知乎专栏,对知识图谱感兴趣的朋友可以关注。标题的命名顺序可能让有的读者不太习惯。通常在介绍一个陌生事物的应用前,我们先给出其定义。之所以换个顺序,是为了不让读者一开始就接触比较冰冷生硬的概念刻板描述(后面我尽量用更具体、准确的例子来表达),另一方面也是为了通过现实生活中的例子自然的引入知识图谱的概念。希望通过这种方式加深读者的印象和理解。为了减轻读者理解的负担,我尽可能地避免引入过多的概念和技术

SimmerChan的专栏 8万+

python解析通达信dat与blk数据文件【附源码】

本文介绍了一个完整的通达信金融数据解析器项目,该项目攻克了通达信专有二进制文件格式解析的技术难题。项目采用模块化架构,从基础二进制解析到增强数据分类,最终实现智能语义化列名生成,形成完整的数据处理链路。核心技术包括自适应编码检测、智能数据类型推断和基于业务规则的语义化处理,解决了逆向工程、多编码兼容性等挑战。项目成果显著,解析成功率达100%,数据可读性大幅提升,开发效率提高50%,为量化交易、可视化分析等场景提供了可靠数据支持。该方案不仅具备技术创新性,更具有实际工程应用价值,为金融数据分析领域提供了可复

qq_36224726的博客 2687

基于51单片机的通讯聊天系统

通过编写51单片机通讯聊天程序,掌握51单片机的各个模块的知识点和运用C语言编写51单片机的能力。用51单片机与口袋开发板设计实现一个单片机与电脑串口助手实现通讯功能的程序。程序的主要功能如下: 1 OLED初始化显示Welcome to Bluetooth communication! 字符串。 2 程序开始时处于接收信息模式, 电脑串口助手发送信息时,将从初始化字符第一个开始显示,电脑串口助手发送信息后,蜂鸣器响铃2秒左右。 3 每次同时按下左右键时,可以轮流切换接收/发送信息模式 4 在发送信息模式时

m0_47419053的博客 3637

【学长笔记】点亮 STM32F411CEU6 板载 LED —— 入门级教程

本文提供了STM32F411CEU6开发板(Black Pill)点亮LED的完整教程。详细介绍了硬件信息(板载LED连接PC13,低电平有效)、CubeMX配置步骤(GPIO输出模式)、Keil5工程设置及完整代码实现(包含GPIO初始化和系统时钟配置)。教程还涵盖ST-Link下载器连接方法、程序下载步骤(需配合BOOT0按键操作)以及验证程序运行的方法。该教程特别适合STM32初学者,通过简单的LED闪烁示例快速入门STM32开发。

apple_53308981的博客 1319

华为od统一考试B卷【单词搜索】C++ 实现

找到它是一个小游戏,你需要在一个矩阵中找到给定的单词。假设给定单词 HELLOWORD,在矩阵中只要能找到 H->E->L->L->O->W->O->R->L->D连成的单词,就算通过。意区分英文字母大小写,并且您只能上下左右行走,不能走回头路。

MISAYAONE的博客 706

RandLA-Net Tensorrt 推理 c++

RandLA-Net 实现 Tensorrt 部署.

J。 1108

【异常】Cursor 编辑器 “Too many computers“ 报错排查与完整解决方案

该报错通常在启动Cursor、调用AI对话/代码补全核心功能时触发,会直接阻断编辑器AI能力的正常使用。

奶爸的编程之路,也就一周冷个三天 451

水与光的奇妙“切割之舞”:水导激光切割技术探秘

水导激光切割技术的诞生,是材料加工领域不断追求高精度、高质量加工的成果。传统激光切割技术在加工过程中,材料会因瞬间高温而产生热变形、热影响区大以及切割面粗糙等问题,这些弊端在对一些高精度、热敏性材料的加工中尤为突出 ,迫切需要一种新的技术来克服这些难题。水导激光切割技术的起源可以追溯到 20 世纪 80 年代。1986 年,德国公司 Aesculap-Werke AG 首次提出了将水流引入激光切割过程的创新想法,并制造出首代水导激光设备。不过,当时的技术尚处于雏形阶段,仅仅是在光纤出口添加了一小柱水流,激光

远程部署调试 运行安装 项目调试 二次开发 项目技术新 持续迭代 部分源码免费分享 1672

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

上一篇: 简单剖析B树(B-Tree)与B+树
下一篇: 部分重要的SOCKET选项
z_ryan
博客等级 码龄9年 255粉丝 43原创
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值