怎样的malloc()内部实现的? [英] How is malloc() implemented internally?
问题描述
任何人都可以解释如何的malloc()
内部工作?
Can anyone explain how malloc()
works internally?
我有时做 strace的程序
,我看到了很多 SBRK
系统调用,这样做<$ C $在男人SBRK
讲座>的malloc()但没有更多。
I have sometimes done strace program
and I see a lot of sbrk
system calls, doing man sbrk
talks about it being used in malloc()
but not much more.
推荐答案
的 SBRK
系统调用移动数据段的边界。这意味着移动的区域的边界,其中一个程序可以读/写数据(使其扩大或缩小,但据我所知没有的malloc
有板有眼内存段回内核与该方法)。除此之外,这里还有 MMAP
这是用来映射文件到内存,但也被用来分配内存(如果你需要分配共享内存, MMAP
是如何做到这一点)。
The sbrk
system call moves the "border" of the data segment. This means it moves a border of an area in which a program may read/write data (letting it grow or shrink, although AFAIK no malloc
really gives memory segments back to the kernel with that method). Aside from that, there's also mmap
which is used to map files into memory but is also used to allocate memory (if you need to allocate shared memory, mmap
is how you do it).
所以,你必须从内核中获得更多的内存的方法有两种: SBRK
和 MMAP
。有关于如何组织你已经从内核足够的内存不同的策略。
So you have two methods of getting more memory from the kernel: sbrk
and mmap
. There are various strategies on how to organize the memory that you've got from the kernel.
一个幼稚的方法是将其划分成区域,通常被称为水桶,这是专门为特定的结构尺寸。例如,的malloc
的实施可为16,64,256和1024字节的结构创建桶。如果你问的malloc
给你一个给定的大小便将这个数字到下一个水桶大小的内存,然后让你从桶的元素。如果你需要一个更大的区域的malloc
可以使用 MMAP
直接与内核分配。如果具有一定规模的桶是空的的malloc
可以使用 SBRK
来得到一个新的水桶更多的空间。
One naive way is to partition it into zones, often called "buckets", which are dedicated to certain structure sizes. For example, a malloc
implementation could create buckets for 16, 64, 256 and 1024 byte structures. If you ask malloc
to give you memory of a given size it rounds that number up to the next bucket size and then gives you an element from that bucket. If you need a bigger area malloc
could use mmap
to allocate directly with the kernel. If the bucket of a certain size is empty malloc
could use sbrk
to get more space for a new bucket.
有各种的malloc
的设计和有propably实施的malloc没有一个正确的方法
如您需要速度,开销和避免分散/空间有效性之间的折衷。例如,如果一个水桶用完元件的实现可能从更大的桶得到的元素,其拆分并将其添加到该跑出元件的桶。这将是相当的空间有效的,但将不可能与每一个设计。如果你只是获得通过 SBRK
/ MMAP
另一个桶,可能是更快,更容易,但不能作为有效空间。此外,设计必须,当然考虑到自由需要做出的可用空间的malloc
再次莫名其妙。你不只是伸手内存没有再使用它。
There are various malloc
designs and there is propably no one true way of implementing malloc
as you need to make a compromise between speed, overhead and avoiding fragmentation/space effectiveness. For example, if a bucket runs out of elements an implementation might get an element from a bigger bucket, split it up and add it to the bucket that ran out of elements. This would be quite space efficient but would not be possible with every design. If you just get another bucket via sbrk
/mmap
that might be faster and even easier, but not as space efficient. Also, the design must of course take into account that "free" needs to make space available to malloc
again somehow. You don't just hand out memory without reusing it.
如果你有兴趣,改进OpenSER / Kamailio SIP代理有两个的malloc
实现(他们需要自己的,因为他们大量使用共享内存和系统<$的C $ C>的malloc 不支持共享内存)。参见:<一href=\"https://github.com/OpenSIPS/opensips/tree/master/mem\">https://github.com/OpenSIPS/opensips/tree/master/mem
If you're interested, the OpenSER/Kamailio SIP proxy has two malloc
implementations (they need their own because they make heavy use of shared memory and the system malloc
doesn't support shared memory). See: https://github.com/OpenSIPS/opensips/tree/master/mem
然后,你还可以看看在 GNU libc的的malloc
实施,而是一个非常复杂,IIRC。
Then you could also have a look at the GNU libc malloc
implementation, but that one is very complicated, IIRC.
这篇关于怎样的malloc()内部实现的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!