Malloc是如何分配内存的?

1.在用户调用malloc之后,系统中发生了什么呢?

首先明确以下几点:

  • 1)malloc是一个C库中的函数,以glibc来说事。
glibc是什么? The GNU C Library, commonly known as glibc, is the GNU Project’s 
implementation of the C standard library
  • 2)glibc是用户空间(userspace)的库。
用户空间和内核空间的划分是为了安全和控制划分的。涉及到分段和分页式的内存管理方式,
Linux内核主要使用分页式的内存管理,按照两级权限和四段来理解(包括用户空间代码段,
用户空间数据段,内核空间代码段和内核空间数据段),在相应的段描述符中有相应的权限位的设置。
  • 3)内存管理中可以理解为分两层,一层是内存地址空间范围,一层是物理地址。而且如果想要使用物理内存,必须要有内存地址空间的虚拟地址并且要和物理地址映射。
在用户程序中想要分配动态内存的时候,首先分配的是内存地址空间,只是一个类似于银行
卡上内钱数的数字(只要我们有足够大的数字,可以进行交易),然后在真正使用内存(读/写等)的时
候(会产生缺页中断)才会真正映射到物理内存(真正进行金银的交易)。

为了安全性,内核不信任用户空间的进程,userspace中的应用只能够分配内存地中空间范围,
而只有内核kernel space才能够分配内存(内核相当于国家,进行金银的管理,
而用户只能进行纸币或者数字的交易)。
  • 4)进程
我们写的userspace的代码(应用程序)在内核的管理中最小的资源分配单位是进程,
这里不用涉及到调度,只涉及资源分配,也就不用管其他的了。

进程在内核中的表示是一个task_struct结构体的实例。其中保存了此进程的所有的资源信息。
其中当然包括内存管理相关的部分,mm_struct。
  • 5)进程的内存地址空间
用户进程可以使用整个虚拟内存空间(32位机器上是0-3G),但是考虑到一个进程实际使用的内存空间
并不是太多,所以一开始进程的地址空间并不是我们所说的0-3G(这只是进程最大能够达到的内存地址空间),

实际的话,会有一个system break,超过这个范围的地址是unmap的地址范围,
实际上也就是可以用而没有用的地址范围。
也就是后面讲到如果一开始的时候分配的地址空间范围不够用的情况下可以进行扩展的地方,
UNIX-like的系统中利用brk或者sbrk或者mmap来扩展process可用的未开垦的地址空间,
也就是修改mm_struct中的start_brk,brk等。

2.这里我们重点关心“系统如何分配了size字节大小的空间”?

  • 从malloc实现功能的角度来看:
void *malloc(size_t size);
我们调用malloc函数,正常情况下,系统(不是只内核)分配了size字节大小的空间,并返回了指向这块空间的指针。
然后我们就开始使用这块动态内存了。
  • malloc分配内存空间实际上并不是我们想的直接到内核中拿一块内存过来用。也不一定访问内核空间。
  • malloc是在userspace的C库函数,它的工作基本在userspace中完成。
    它只是向glibc请求内存空间(虚拟地址空间),相当于glibc帮助我们写的进程来管理已经分配的内存地址空间。

    也就是glibc持有一定量的属于我们进程的内存地址空间(注意不是实际的物理内存空间)。
    主要是初始分配或者通过brk和sbrk或者mmap向内核批发的,然后“卖”给我们coder使用。
    (1)所以malloc首先向glibc查询是否有足够大小的内存空间可用,如果可用,分配返回就好了,malloc函数也就完成了。上面已经说过,真正使用的时候才会产生缺页中断由内核来分配实际的物理内存。
    (2)如果glibc中管理的本进程的内存地址空间不够分配了,那么malloc将会触发批发操作:brk或者sbrk或者mmap。
    brk、sbrk或者mmap会修改这个进程的内存地址空间相关的信息(上面已经说了是task_struct->mm_struct->brk等),相当于进程映射的空间变多了,未开垦的空间又开垦了一些,glibc持有的空间变大了,可以够分配给malloc了,那就分给它就好了。
    (3)最终上层应用程序中语句开始使用这块分配的内存的时候,触发缺页中断,内核分配物理内存。

参考:

Malloc是如何分配内存的?
https://blog.csdn.net/aganlengzi/article/details/51339493
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值