c - malloc() 是如何在内部实现的?

标签 c memory malloc system-calls sbrk

谁能解释一下 malloc() 在内部是如何工作的?

我有时会做 strace program 并且我看到很多 sbrk 系统调用,做 man sbrk 谈论它被用于 malloc() 但仅此而已。

最佳答案

sbrk系统调用移动数据段的“边界”。这意味着它移动了程序可以读取/写入数据的区域的边界(让它增长或缩小,尽管 AFAIK no malloc 确实使用该方法将内存段返回给内核)。除此之外,还有 mmap 用于将文件映射到内存,但也用于分配内存(如果您需要分配共享内存,mmap 就是你的做法它)。

所以你有两种从内核获取更多内存的方法:sbrkmmap。关于如何组织从内核获得的内存有多种策略。

一种天真的方法是将其划分为区域,通常称为“桶”,专用于某些结构大小。例如,malloc 实现可以为 16、64、256 和 1024 字节结构创建存储桶。如果您要求 malloc 为您提供给定大小的内存,它将将该数字四舍五入到下一个桶大小,然后为您提供该桶中的一个元素。如果你需要更大的区域malloc 可以使用mmap 直接分配给内核。如果某个大小的桶是空的,malloc 可以使用 sbrk 为新的桶获取更多空间。

malloc 设计多种多样,可能没有一种真正的方式来实现 malloc,因为您需要在速度、开销和避免碎片/空间效率之间做出折衷.例如,如果一个桶用完了元素,一个实现可能会从一个更大的桶中获取一个元素,将其拆分并将其添加到用完元素的桶中。这将非常节省空间,但并非每种设计都可能。如果您只是通过 sbrk/mmap 获得另一个存储桶,这可能会更快,甚至更容易,但空间效率不高。此外,设计当然必须考虑到“免费”需要以某种方式再次为 malloc 提供可用空间。你不会只分配内存而不重用它。

如果您有兴趣,OpenSER/Kamailio SIP 代理有两个 malloc 实现(它们需要自己的实现,因为它们大量使用共享内存和系统 malloc不支持共享内存)。见:https://github.com/OpenSIPS/opensips/tree/master/mem

那你也可以看看GNU libc malloc implementation ,但是那个很复杂,IIRC。

关于c - malloc() 是如何在内部实现的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3479330/

相关文章:

c - 选择排序字符 C

ruby - JSON的基于流的解析和写入

c - 在结构中保存指向数组的指针

cJSON打印函数不向对象添加数字

将用户输入转换为 unicode

c++ - 如何编写没有任何字母但只能使用主词的c代码?

c - 为什么 c 第二次打印时打印不同的数组?

iphone - 尝试由不同的类加载时 TableView 崩溃

java - Java 8 与 Java 9 之间的内存分配是否存在差异?

c - 为什么在 malloc 中使用 sizeof(*pointer) 更安全