malloc如何从堆中获取内存?

Posted

技术标签:

【中文标题】malloc如何从堆中获取内存?【英文标题】:How does malloc obtain memory from the heap? 【发布时间】:2021-01-10 05:28:24 【问题描述】:

我们知道malloc 在内部调用mmap。但是mmap不一定会映射到堆上,因为mmap可以将对象映射到虚拟内存中的任意区域,那么malloc在内部如何确保请求的内存大小来自堆呢?

【问题讨论】:

你有一个错误的前提。堆是malloc() 使用的任何内存,它不是特定的内存区域。 另外,mmap() 只是实现malloc() 的一种可能方式。传统方式使用sbrk(),它只是扩展了数据段,所以它连续的。 另外说:“堆”被定义为malloc交给你的任何内存。它从哪里获得它是一个内部细节,该细节因平台而异(例如,在嵌入式上,如果你有malloc,你通常会硬编码编译时可用的物理内存的一部分)。 对。堆不是虚拟内存的单个区域。它是malloc() 管理的所有内存区域的集合。 @Barmar Linux 进程确实有一个“特殊”的虚拟机区域,它称为“堆”。只需grep heap /proc/self/maps。这仅适用于brk 获得的内存。第一个参数为 NULL 的常规 mmap(无论是由 malloc 调用还是其他)不会在该区域创建映射。因此,并非所有 malloc 的内存都是“堆”;-) 请不要没有真正的苏格兰人。 【参考方案1】:

malloc 使用mmap 分配内存时,它并不关心内存来自哪里——它将分配委托给mmap,并依靠它来提供可用的内存块。

在 GNU C 库中(也可能在其他实现中),此类分配与使用 sbrk 管理的分配分开跟踪。所有涉及mmaped 分配的操作也被委托(重新分配和释放)。

从内核的角度来看,这种分配是堆外的,在程序中断之后。从程序员的角度来看,它们都是一样的;与sbrk-only 分配相比,主要的实际后果是你不能假设分配的块在程序中断内,或者两个分配的块之间的地址空间是可访问的,但无论如何你都不应该这样做。

另请参阅 the POSIX specification for malloc — 它没有说明堆的任何内容。

【讨论】:

以上是关于malloc如何从堆中获取内存?的主要内容,如果未能解决你的问题,请参考以下文章

Python:从堆中删除元素

new 与malloc的区别

如何获取由函数“malloc”锁定的内存段指针的大小 [重复]

C标准库 | 内存分配以及释放函数汇总

装箱与拆箱

堆中的 DLL 内存泄漏