Windows内存分配问题

5
我目前正在研究Windows下的malloc()实现。但在我的研究中,我遇到了一些让我感到困惑的事情:
首先,我知道在API层面上,Windows主要使用HeapAlloc()VirtualAlloc()调用来分配内存。从这里收集到的信息表明,Microsoft实现的malloc()(包含在CRT - C运行时中)基本上为大于480字节的块调用HeapAlloc(),而对于小的分配,则管理一个使用VirtualAlloc()分配的特殊区域,以防止碎片化。
好吧,这一切都很好。但是还有其他的malloc()实现,例如nedmalloc,声称比Microsoft的malloc快高达125%。
所有这些让我想知道一些事情:
  1. 为什么我们不能只调用HeapAlloc()来分配小块内存?它在碎片化方面表现不佳吗(例如采用“首次适配”而不是“最佳适配”)?

    • 实际上,有没有办法知道各种API分配调用的内部情况?那将非常有帮助。
  2. 是什么让nedmalloc比Microsoft的malloc快得多?

  3. 从上面的内容中,我得出的印象是HeapAlloc()/VirtualAlloc()如此缓慢,以至于malloc()很少调用它们,然后自己管理已分配的内存。这个假设是否正确?还是malloc()“包装器”仅仅是因为碎片化?人们会认为这样的系统调用会很快 - 或者至少会有一些想法使它们高效。

    • 如果这是真的,为什么会这样?
  4. 平均而言,一个典型的malloc调用执行多少次内存读/写操作(可能是已分配段的函数数量级)?我直觉上会说对于一个平均程序来说,这个数字在十几次左右,我对吗?


顺便提一下,阅读有关“dlmalloc”的内容可以很好地了解malloc策略。 - Will
2个回答

5
  1. 调用HeapAlloc听起来不太跨平台。微软可以在任何时候更改其实现方式;建议避免使用。 :)
  2. 它可能更有效地使用内存池,就像Loki库使用其“小对象分配器”一样。
  3. 由于堆分配本质上是通用的,因此通过任何实现方式都很慢。分配器越“专业化”,速度越快。这将我们带回到第二点,涉及内存池(以及特定于应用程序的分配大小)。
  4. 不知道。

微软也可以自由更改事物以使一切变得更好。请查看转换到低碎片堆。 - MSN
  1. 我也没想到会这样,因为我正在尝试针对Windows实现malloc。但问题仍然存在:从碎片化的角度来看,它是否无效?
  2. 您的意思是它可以更有效地管理指向空闲空间的指针,以便更快地分配适当的内存块?您知道在哪里可以阅读有关内存池的信息吗?
正如用户Will所建议的那样,我已经开始使用dlmalloc(我之前曾浏览过它,但它听起来是面向Unix的,将其Windows功能描述为模拟Unix调用)。
- Norswap

1
从上面的内容中,我得到的印象是HeapAlloc()/VirtualAlloc()非常慢,所以对于malloc()来说,只有在必要时才调用它们并自己管理分配的内存会更快。这个假设是否正确?
操作系统级别的系统调用被设计和优化用于管理进程的整个内存空间。使用它们来分配4个字节的整数确实是次优的——通过在库代码中管理微小的分配,并让操作系统针对较大的分配进行优化,您可以获得更好的性能和内存使用率。至少就我理解而言。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接