谁能解释一下 malloc()
在内部是如何工作的?
我有时会做 strace program
并且我看到很多 sbrk
系统调用,做 man sbrk
谈论它被用于 malloc()
但仅此而已。
最佳答案
sbrk
系统调用移动数据段的“边界”。这意味着它移动了程序可以读取/写入数据的区域的边界(让它增长或缩小,尽管 AFAIK no malloc
确实使用该方法将内存段返回给内核)。除此之外,还有 mmap
用于将文件映射到内存,但也用于分配内存(如果您需要分配共享内存,mmap
就是你的做法它)。
所以你有两种从内核获取更多内存的方法:sbrk
和 mmap
。关于如何组织从内核获得的内存有多种策略。
一种天真的方法是将其划分为区域,通常称为“桶”,专用于某些结构大小。例如,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/