当存储块请求不是2的幂时会发生什么?

时间:2010-07-23 08:00:04

标签: c linux malloc

假设我们对大小为n的内存块执行malloc请求,其中对于k> 0,2 ^ k!= n。 Malloc为请求的内存块返回空间,但是如何从页面处理stillig缓冲区。我读过Pages通常是内存块,它们是2的幂。

Wiki声明如下:

 Like any method of memory allocation, the heap will become fragmented; that is,
 there will be sections of used and unused memory in the allocated 
 space on the heap. A good allocator will attempt to find an unused area
 of already allocated memory to use before resorting to expanding the heap.

所以我的问题是这是如何跟踪的?

编辑:使用malloc时如何跟踪未使用的内存?

3 个答案:

答案 0 :(得分:3)

这实际上取决于具体的实施,正如Morten Siebuhr已经指出的那样。在非常简单的情况下,可能存在一系列可用的,固定大小的内存块(可能都具有相同的大小),因此未使用的内存被浪费掉了。请注意,实际实现永远不会使用这种简单的算法。

这是对一些简单可能性的概述:http://www.osdcom.info/content/view/31/39/

此维基百科条目有几个有趣的链接,包括上面的一个:http://en.wikipedia.org/wiki/Dynamic_memory_allocation#Implementations

作为最后的评论,谷歌搜索“malloc实现”变成了一堆有价值的链接(双关语)。

答案 1 :(得分:3)

标准的BSD风格的内存分配器基本上是这样的:

  • 它保留了预先分配的内存块的链表,大小为2 ^ k,k <= 12(例如)。
  • 实际上,给定k的每个列表都由来自不同区域的内存块组成,见下文。
  • 通过计算n',最接近的2 ^ k&gt; = n来服务n个字节的malloc请求,然后在列表中查找k的第一个区域,然后返回第一个给定区域的空闲列表中的空闲块
  • 当没有预先分配的大小为2 ^ k的内存块时,会分配一个区域,一个区域是一段较大的连续内存,比如一块4kB的内存。然后将这块存储器切割成2 ^ k字节的片段。在连续存储区域的开头有书籍信息,例如在哪里可以找到该区域内的空闲块的链接列表。也可以使用位图,但链表通常具有更好的缓存行为(您希望下一个已分配的块返回已存在于缓存中的内存)。
  • 使用区域的原因是free(ptr)可以有效实现。 ptr&amp;此示例中的0xfffff000指向包含簿记结构的区域的开头,并且可以将内存块链接回该区域。
  • BSD分配器将通过总是返回大小为2 ^ k的内存块来浪费空间,但它可以重用块的内存来保留空闲列表,这是一个不错的属性。分配也非常快。

对上述一般想法的修改包括:

  • 使用匿名mmap进行大量分配。这将工作转移到内核以处理大型mallocs,并避免在这些情况下浪费大量内存。
  • malloc的GNU版本具有非二次幂桶的特殊情况。 BSD分配器中没有固有的东西需要返回2 ^ k个内存块,只有有预定义的桶大小。 GNU分配器具有更多桶,因此浪费更少的空间。
  • 在线程之间共享内存是一个棘手的主题。分配期间的锁争用是一个重要的考虑因素,因此在GNU分配器中,如果在分配期间遇到锁争用,则会针对给定存储桶大小的不同线程急切地创建额外的区域

答案 2 :(得分:2)

从实现到实现,这有很多很多。有些人浪费了空间,一些细分页面直到他们得到所要求的尺寸(或接近它)&amp; c。

如果您是出于好奇,我建议您阅读相关实施的源代码,

如果是因为性能问题,请尝试对其进行基准测试,看看会发生什么。