c - malloc 会四舍五入到最接近的页面大小吗?

标签 c malloc mmap brk

我不确定我在这里问的是不是菜鸟问题,但我开始了。我也搜索了很多类似的问题,但一无所获。

所以,我知道 mmapbrk 是如何工作的,而且无论您输入的长度是多少,它都会将其四舍五入到最近的页面边界。我也知道 malloc 使用 brk/sbrkmmap (至少在 Linux/Unix 系统上)但是这会引发问题:malloc 是否也四舍五入到最接近的页面大小?对我来说,页面大小是 4096 字节,所以如果我想用 malloc 分配 16 字节,4096 字节是......比我要求的多很多。

最佳答案

malloc 及其 friend 的基本工作是管理这样一个事实,即操作系统通常只能(有效地)处理大型分配(整页和页范围),而程序通常需要更小的 block 和更细粒度的管理。

所以 malloc(通常)所做的是,第一次调用它时,它会从系统分配大量内存(通过 mmap 或 sbrk——可能是一页或可能是许多页),并使用较小的内存一些数据结构的数量用于跟踪堆使用(堆在哪里,哪些部分正在使用以及哪些部分是空闲的),然后将该空间的其余部分标记为空闲。然后,它会从该可用空间分配您请求的内存,并保留其余内存以供后续 malloc 调用使用。

因此,当您第一次为 16 字节调用 malloc 时,它将使用 mmap 或 sbrk 分配一个大块(可能是 4K 或可能是 64K 或可能是 16MB 甚至更多)并将其初始化为大部分空闲并返回给您一个指针到 16 字节的地方。第二次调用 malloc 获取另外 16 个字节只会从该池中返回另外 16 个字节——无需返回操作系统获取更多。

随着您的程序继续分配更多内存,它将仅来自该池,并且免费调用会将内存返回到空闲池。如果通常分配的内存多于释放的内存,最终空闲池将用完,此时,malloc 将调用系统(mmap 或 sbrk)以获取更多内存以添加到空闲池。

这就是为什么如果您使用某种进程监视器监视正在使用 malloc/free 分配和释放内存的进程,您通常只会看到内存使用量上升(因为空闲池用完并且请求更多内存从系统),并且通常不会看到它下降 - 即使内存正在被释放,它通常只是回到空闲池并且不会取消映射或返回到系统。有一些异常(exception)——特别是如果涉及非常大的 block ——但通常在进程退出之前,您不能依赖任何内存返回给系统。

关于c - malloc 会四舍五入到最接近的页面大小吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65931325/

相关文章:

c - 为什么在向后打印文本文件的程序中调用 fseek 时应使用偏移量 -2 而不是偏移量 -1?

java - 如何在Java中从C文件中获取方法和参数的名称?

c - 在 C 中释放返回的变量

c - 关于通过 mmap(2) 优化文件读写的问题?

c - 使用 mmap() 搜索大文件 (~1TB)

c - 获取大于 RAND_MAX 范围内的随机数 (C)

c - 无法释放分配的内存

c - 如何找到malloc分配的字节数

FreeBSD 上的 Python 字符串内存使用情况

linux - 如何通过替换为空页映射来取消映射 mmap 文件