Linux系统用户空间分配

来自《Linux/UNIX系统编程手册》内存分配一章

Linux的进程用户空间内存布局(实际上是简化版)

在这里插入图片描述
主要关注这五个段(更准确的说是“区(section)”):

  • 文本段:存放程序代码,只读。因为代码可以被多个进程共享,所以在物理空间实际上只有一份
  • 初始化数据段:存放初始化的全局变量和静态变量,程序加载时从可执行文件读取
  • 未初始化数据段:一般称作BSS段,存放未初始化的全局变量和静态变量,在程序执行前全部被初始化为0,这样在可执行文件中就不用记录数据的值,只要给一个段的位置和长度,直到加载时才分配空间
  • 栈:由栈帧组成,每个函数被调用时会分配一个栈帧,存放局部变量、实参、返回值等等,向地址减小方向增长
  • 堆:用于动态分配内存的区域,堆顶称为program break,从BSS段尾部向地址增大方向增长

应用程序分配内存可以从栈或者堆上分配

从堆上分配

调整堆的大小也就是调整program break的位置,Linux提供了两个系统调用,brk()和sbrk()

  • int brk(void *end_data_segment)将program break调整为参数end_data_segment指定位置,由于内存分配按照页为单位,所以实际上内部会调整program break到页的边界,注意brk可以让program break上升也可下降
  • void *sbrk(intptr_t increment)将program break加上increment,这是个整数类型即program break可以上升也可以下降,sbrk(0)将返回当前program break位置
    一般来说我们习惯使用malloc()和free()来分配和释放动态内存,他们的实现实际上使用了brk()和sbrk()两个调用
  • void *malloc(size_t size)分配size字节大小的内存,一般来说实际分配时会内存对齐
  • void free(void *ptr)释放内存

free()一般并不会降低program break的位置,而是将内存添加到空闲内存列表(后面会展示),只有当在堆的顶部释放时,并且当堆顶连续空闲空间足够大时才会调用sbrk()调整program break

malloc()和free()的实现

当调用malloc()时扫描空闲内存列表,然后找一块大小大于等于要求的空闲内存(这里看具体的实现使用什么策略比如best-fit或者first-fit等等),如果大小相等就返回,如果大小超过要求就切割出来一部分,然后将剩余部分留在空闲内存列表中。如果没有满足要求的空闲内存,才会用sbrk()分配更多内存。
调用free()时回收内存并放入空闲内存列表。当malloc分配内存时实际上会额外分配几个字节来记录分配的内存大小,如下图:
在这里插入图片描述
所以free在回收时就能知道内存块的大小,将内存块放进空闲内存列表时,会利用内存本身的空间来存放链表指针,将所有空闲内存块串起来:
在这里插入图片描述
那么实际上堆中的内存应该是这样管理的:
在这里插入图片描述

realloc()调整分配内存

通常当我们需要增大已分配的内存空间时,使用void *realloc(void *ptr, size_t size)将ptr位置的内存变为size字节大小。
增大已经分配的内存,realloc()首先会尝试合并紧随已分配内存后的空闲内存,如果说已分配内存在堆顶部那么会扩展堆空间;如果找不到这样的空闲内存或者空闲内存不够大,那么需要重新分配一块大内存,并将原来的部分复制过去,因此调用realloc后原指针可能失效。


在栈上分配内存

使用void *alloc(size_t size)可以扩展当前函数栈帧的大小,这样分配的内存是临时的,所以不能用free()来释放,相对于malloc它是直接调整栈指针所以速度快,而且在函数返回时分配的内存就会被销毁,无需自己释放,在部分场合可以发挥较好的效果。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值