malloc的底层实现(ptmalloc)

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

前言

  本文主要介绍了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万+

【C语言】malloc()函数详解(动态内存开辟函数)

C语言库函数malloc()函数的功能,参数,返回值及具体使用详解.

C/C++领域,数据结构,linux,MySQl学习者 7万+

浅析malloc底层实现原理(ptmalloc

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

ZY-JIMMY 4514

C语言malloc函数的用法

在使用malloc函数前,需要调用头文件# include <malloc.h> malloc函数的作用是动态分配内存,以解决静态内存定长、不能手动释放等缺陷。 malloc的使用方法: int *p = (int*)malloc(sizeof(int)); *p = 1; free(p); 其中,p为一个整型指针变量,由int *p = (int*)malloc(sizeof(int))可以看出来,这句话在给*p分配内存. malloc函数支持一个形参(该形参就是字节大小),而sizeof(

qq_43511299的博客 6万+

malloc底层实现ptmalloc)---转载

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声...

qq_43686340的博客 227

[系统安全] 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的博客 1332

堆内存的逆袭:从 malloc 底层机制看高性能编程

在 Linux 服务器开发的修罗场中,内存管理向来是兵家必争之地。当我们轻描淡写地写下malloc(n)时,这块动态分配的内存背后,正上演着一场关于性能与效率的精密博弈。本文将撕开 C 语言内存分配的神秘面纱,从 glibc 的 ptmalloc 实现出发,解析高性能程序背后的内存管理哲学。

Cheese_Y的博客 1158

new和malloc的区别、ptmalloc

一、new和malloc的区别 1、new/delete是C++的运算符/关键字,malloc与free是c++/c语言的标准函数 void* malloc(size_t); void free(void*); void *operator new (size_t); void operator delete (void *); void *operator new[] (size_t); ...

lisaaaaaas0405的博客 514

malloc 背后的虚拟内存 和 malloc实现原理

面试的时候经常会被问到 malloc实现。从操作系统层面来说,malloc 确实是考察面试者对操作系统底层的存储管理理解的一个很好的方式,涉及到虚拟内存、分页/分段等。下面逐个细说。 1. 虚拟内存 首先需要知道的是程序运行起来的话需要被加载的物理内存中,具体到计算机硬件就是内存条。操作系统启动的时候先把自己加载到物理内存的固定位置(一般为底部),物理内存的其他位置就用来运行用户程序。程序就是一堆指令,程序运行可以简单抽象为把指令加载到内存中,然后 CPU 将指令从内存载入执行。 1. 为什么需要

yizhiniu_xuyw的专栏 1902

malloc(ptmalloc) 源码底层逻辑分析(_int_malloc)

本文记录了作者深入研究glibc中malloc实现的过程。作者从最初的困惑出发,通过AI工具指引找到glibc源码,使用sed工具处理源码格式,最终定位到关键函数_int_malloc。文章详细解析了malloc的内存管理机制,包括chunk结构、bins数组、tcache线程缓存等核心概念,重点剖析了smallbin和largebin的分配策略,以及unsorted bin的处理逻辑。作者通过源码分析和宏定义解读,揭示了malloc如何高效管理内存分配,包括内存对齐检查、最佳适配算法、位图优化等关键技术。

QQ2451421621的博客 711

Linux:malloc背后的实现细节

作为C/C++中最基础的动态内存分配函数,malloc看似简单(),但其背后涉及操作系统、内存管理、性能优化等多层复杂机制。作为新手,理解这些细节能帮你避免内存泄漏、碎片化等常见问题。历史:glibc 早期基于dlmalloc,后来引入了ptmalloc2,增加了多线程支持。

小嵌同学的博客 1539

malloc 是如何分配内存的?——C 语言内存分配详解

/ 内存块头部结构// 内存块大小(不包含头部)// 是否空闲// 指向下一个内存块} MemBlock;// 全局内存池和头部指针// 初始化内存池// 分配大块内存if (!// 初始化第一个内存块// 分配内存if (!// 默认1MB内存池// 查找最佳匹配的空闲块if (!// 没有找到合适的空闲块if (!// 如果剩余空间足够大,分割内存块// 释放内存if (!// 获取内存块头部。

w148_1748的博客 1522

malloc底层工作原理——ptmalloc

概述 本文主要分析ptmalloc中的对于每个内存块的管理方法:边界标志法和所有内存块的整体管理:分箱式内存管理。以及malloc()函数和free()函数的底层原理和工作步骤。 边界标志法 ptmalloc使用chunk实现内存管理,不管内存是在哪里被分配的,用什么方法分配,用户请求分配的空间在ptmalloc中都使用一个chunk来表示。用户调用free()函数释放掉的内存也并不是立即归...

Mr_H9527的博客 1958
上一篇: 简单剖析B树(B-Tree)与B+树
下一篇: 部分重要的SOCKET选项
z_ryan
博客等级 码龄9年 255粉丝 43原创
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值