进程内存布局 - 堆、数据和 mmap 区域之间的区别

进程内存布局 - 堆、数据和 mmap 区域之间的区别

我在网上看到许多关于 Linux 进程的内存布局的相互矛盾或不清楚的描述。通常情况下常用图好像:

在此输入图像描述

还有一个常见的描述会说:

数据段仅包含具有预定义值并且可以修改的全局或静态变量。堆包含动态分配的数据,这些数据存储在我们称为堆部分的内存部分中,该部分通常从数据段结束的地方开始。

:

一般来说,堆是由 C 运行时创建并管理的一个特定内存区域malloc(反过来使用brksbrk系统调用来增长和收缩)。

mmapmalloc是一种独立于(因此独立于堆) 创建新内存区域的方法 。munmap只是它的逆过程,它释放这些区域。

其中许多解释似乎已经过时,而且我发现许多差异。例如,许多文章 - 正如上面的答案 - 声称堆被使用 my malloc,但这实际上是一个使用sbrkor 的库调用mmap,作为malloc 手册页说:

通常,malloc()从堆中分配内存,并根据需要调整堆的大小,使用sbrk(2).当分配的内存块大于MMAP_THRESHOLDbytes,glibc malloc()实现使用 .bytes 将内存分配为私有匿名映射mmap(2)

那么如果malloc在很多情况下都是由 实现的mmap,那么堆和 mmap 区域之间有什么区别呢?

另一件看似矛盾的事情是,许多文章(如malloc手册页本身)声称brk/sbrk调整堆的大小,但他们的手册页说它实际上调整了大小数据段:

brk()sbrk()更改位置程序中断,它定义了进程数据段的末尾(即程序中断是未初始化数据段末尾之后的第一个位置)。

因此,我试图对当今不同段的进程的内存布局进行清晰、最新的整体解释,这也解决了这些问题:

  1. 堆和 mmap 区域有什么区别? (从我尝试的一些测试来看,通过查看我获得的地址mmap并与 中的堆范围进行比较/proc/self/maps,似乎一些mmap分配的页面实际上是在堆段内分配的。)
  2. 是否休息意味着结束数据段,或结束

其他相关问题:

相关内容