前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >brk与mmap

brk与mmap

作者头像
Orlion
发布2024-09-02 16:32:54
710
发布2024-09-02 16:32:54
举报
文章被收录于专栏:我的独立博客

1. 前言

glibc的malloc函数在申请大于128K的内存时使用mmap分配内存,mmap会从堆区和栈区中间的部分划分内存,而在申请小于128K的内存时使用brk从堆上划分内存。

2. brk/sbrk

brk是linux上一个系统调用,而sbrk是一个C库函数

2.1 brk函数原型

代码语言:javascript
复制
int brk(void *addr);
参数

参数

解释

addr

要调整到的内存地址

返回值

返回增加的大小

2.2 sbrk函数原型

代码语言:javascript
复制
void *sbrk(intptr_t increment);
参数

参数

解释

increment

增加的内存大小

返回值

返回增加之后的program break内存地址

2.3 brk的原理

brk实际是通过改变program break来实现的,这个program break可以理解为“堆顶指针”,意味着程序堆内存使用到了该位置。

而这种内存的分配方式有个问题,看下下图:

假设B已经被free了,但是由于上面有一个C对象,所以program break指针不能简单的向下移动来释放内存。那怎么办呢?

实际上free后不能立即归还内存,只是将这块内存标记为空闲,后续再申请内存时可以复用这块内存。并且两块连续的空闲内存可以合并为一块空闲内存,当最高地址空间的空闲内存大于128K时(可以通过M_TRIM_THRESHOLD选项调节),执行内存紧缩。对于上图来说,如果C也被free了,program break就可以指向A的结束地址了,就能释放一部分内存了。

难道这就是传说中的线性内存分配

3. mmap

3.1 mmap函数原型

代码语言:javascript
复制
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
参数

参数

解释

addr

映射的起始地址,通常设置为NULL,由内核来分配

len

指定将文件映射到内存的部分的长度

prot

映射区域的保护方式,通常是下面几个选项的组合

flags

映射区的特性标志位,常用的有以下两个选项

fd

要映射到内存中的文件描述符

offset

文件映射的偏移量,必须是操作系统内存页大小的整数倍

返回值

返回映射区的起始地址

3.2 munmap函数原型

代码语言:javascript
复制
// 解除映射
int munmap(void *start, size_t length);
参数

参数

解释

start

mmap返回的映射区的起始地址

length

映射区的大小

返回值

解除成功返回0,失败返回-1

3.3 mmap原理

linxu内核使用vm_area_struct结构来表示一个独立的虚拟内存区域(比如堆、栈、bss段、代码段等),一个进程会有多个vm_area_struct结构体,各个vm_area_struct使用树结构或者链表连接。

vm_area_struct结构包含了该区域的起止地址和其他信息以及一个vm_ops指针,vm_ops指针内部引出所有针对这个区域可用的系统调用函数。

mmap就是创建一个新vm_area_struct结构,并将其与文件磁盘地址做映射。

mmap申请的内存可以通过munmap释放。

4. 总结

方式

内存碎片

适用场景

brk

多,因为不可释放

申请小内存

mmap

无,因为可以直接释放

申请大内存,如果用来申请小内存的话就会创建非常多的vm_area_struct结构体,不划算

5. 参考资料

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-06-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 前言
  • 2. brk/sbrk
    • 2.1 brk函数原型
      • 2.2 sbrk函数原型
        • 2.3 brk的原理
        • 3. mmap
          • 3.1 mmap函数原型
            • 3.2 munmap函数原型
              • 3.3 mmap原理
              • 4. 总结
              • 5. 参考资料
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档