malloc的底层实现原理

关于内存分配:

  • 一些全局变量,static变量是在编译期间就分配好内存空间,他们都被放在静态存储区,生命周期随进程
  • 局部变量是在程序运行期间才分配空间,在栈上进行分配,一旦离开局部作用域,栈上的空间会自动释放,因为栈空间有限
  • 程序运行时我们使用malloc/calloc/realloc来在堆上申请内存空间,当手动调用free的时候堆上申请的空间会被释放,它的生命周期由程序员自身决定

函数原型:

#include <stdlib.h>

void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t nmemb,size_t size);
void *realloc(void *ptr,size_t size);

他们之间的区别:

  • malloc需要手动计算所需要的空间字节数作为参数
  • calloc中的第一个参数是元素个数,第二个是单个元素的大小。并且calloc会将空间中每个字节初始化为0
  • realloc是对动态开辟空间大小的调整,第一个参数是原地址空间的首地址,第二个参数是调整后的大小

realloc在申请空间时有两种情况,
第一种:原空间后有足够大小的空间,就会直接在后面进行追加到size大小,原来数据不变,返回值还是原空间起始地址
第二种:原空间后无足够大小的空间,会在堆上重新找一块满足需求的空间来使用,然后将原空间数据搬移到新空间,free掉旧空间,再返回新空间的起始地址。

malloc的底层实现?

Linux下的实现原理:
Linux维护一个break指针,这个指针指向堆空间的某个地址。从堆起始地址到break之间的地址空间为映射好的,可以供进程访问;而从break指针往上是未映射的地址空间,如果访问这段空间则程序会报错。我们用malloc进行内存分配就是从break往上进行的。获得了break指针的位置也就得到了堆内存申请的起始位置。malloc实际上是将可用空间用一个空闲链表连接起来,若用户申请空间,就遍历该链表,找到第一个满足条件的空闲内存块,将其进行拆分,返回合适大小的空间给用户,将剩下的部分连接到链表中。当free释放空间时,会把这块空间连接到空闲链表上。

到最后,该空闲链就会被切成很多的小内存块,一旦用户申请一块较大的空间,空闲链中的空间大小都无法满足需求,malloc会申请延时,对空闲链表进行检查,内存重新整理,把相邻的小片段合并成大的空闲块。

搜索空闲块最常见的算法有:首次适配,下一次适配,最佳适配。
首次适配:第一次找到足够大的内存块就分配,这种方法会产生很多的内存碎片。
下一次适配:也就是说等第二次找到足够大的内存块就分配,这样会产生比较少的内存碎片。
最佳适配:对堆进行彻底的搜索,从头开始,遍历所有块,使用数据区大小大于size且差值最小的块作为此次分配的块

malloc中实际调用了brk(),sbrk()函数

#include <unistd.h>

//函数原型:
int brk(void *addr);
void *sbrk(intptr_t increment);

这两个函数都用来改变break指针的位置,改变数据段长度,实现虚拟内存到物理内存的映射。
brk()函数直接修改有效访问范围的末尾地址实现分配与回收。
!!注意:当使用malloc()函数分配过大的空间时,malloc不再从堆中分配空间,而是使用mmap()这个系统调用从映射区寻找可用的内存空间。

1)当开辟空间小于128K时,调用brk()函数,malloc的底层是现实系统调用函数brk(),其主要移动指针_enddata来开辟空间。
2)当开辟空间大于128k时,mmap()系统调用函数在虚拟地址空间中找一块空间来开辟。

————————————————
版权声明:本文为CSDN博主「是蛋筒啊」的原创文章,遵循CC 4.0 BY-SA版权协议,
原文链接:https://blog.csdn.net/shidantong/article/details/81835694

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值