我在网上看到许多关于 Linux 进程的内存布局的相互矛盾或不清楚的描述。通常情况下常用图好像:
还有一个常见的描述会说:
数据段仅包含具有预定义值并且可以修改的全局或静态变量。堆包含动态分配的数据,这些数据存储在我们称为堆部分的内存部分中,该部分通常从数据段结束的地方开始。
和还:
一般来说,堆是由 C 运行时创建并管理的一个特定内存区域
malloc
(反过来使用brk
和sbrk
系统调用来增长和收缩)。
mmap
malloc
是一种独立于(因此独立于堆) 创建新内存区域的方法 。munmap
只是它的逆过程,它释放这些区域。
其中许多解释似乎已经过时,而且我发现许多差异。例如,许多文章 - 正如上面的答案 - 声称堆被使用 my malloc
,但这实际上是一个使用sbrk
or 的库调用mmap
,作为malloc
手册页说:
通常,
malloc()
从堆中分配内存,并根据需要调整堆的大小,使用sbrk(2)
.当分配的内存块大于MMAP_THRESHOLDbytes,glibcmalloc()
实现使用 .bytes 将内存分配为私有匿名映射mmap(2)
。
那么如果malloc
在很多情况下都是由 实现的mmap
,那么堆和 mmap 区域之间有什么区别呢?
另一件看似矛盾的事情是,许多文章(如malloc
手册页本身)声称brk
/sbrk
调整堆的大小,但他们的手册页说它实际上调整了大小数据段:
brk()
并sbrk()
更改位置程序中断,它定义了进程数据段的末尾(即程序中断是未初始化数据段末尾之后的第一个位置)。
因此,我试图对当今不同段的进程的内存布局进行清晰、最新的整体解释,这也解决了这些问题:
- 堆和 mmap 区域有什么区别? (从我尝试的一些测试来看,通过查看我获得的地址
mmap
并与 中的堆范围进行比较/proc/self/maps
,似乎一些mmap
分配的页面实际上是在堆段内分配的。) - 是否休息意味着结束数据段,或结束堆?
其他相关问题: