Windows内存分配问题

时间:2010-07-07 22:30:34

标签: windows memory-management malloc dynamic-memory-allocation nedmalloc

我目前正在调查Windows下的malloc()实施。但在我的研究中,我偶然发现了困扰我的事情:

首先,我知道在API级别,Windows主要使用HeapAlloc()VirtualAlloc()调用来分配内存。我从here收集了malloc()的Microsoft实现(包含在CRT中的那个 - C运行时)基本上调用HeapAlloc()来获取块> 480字节,否则管理分配有VirtualAlloc()的特殊区域用于小分配,以防止碎片。

这一切都很好,很好。但是,还有malloc()的其他实现,例如nedmalloc,声称比微软的malloc快了125%。

这一切让我想到了一些事情:

  1. 为什么我们不能只为小块调用HeapAlloc()?在碎片方面表现不佳(例如通过“先适合”而不是“最适合”)?

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

  3. 从上面可以看出,HeapAlloc() / VirtualAlloc()速度太快,以至于malloc()只能偶尔调用一次,然后才会更快管理分配的内存本身。这个假设是真的吗?或者是因为碎片而需要malloc()“包装器”? 有人会认为像这样的系统调用会很快 - 或者至少会有一些想法被放入其中以使它们有效。

    • 如果是真的,为什么会这样?
  4. 平均而言,典型的malloc调用执行了多少(一个数量级)的内存读/写(可能是已分配段数的函数)?我会直观地说它是一个普通程序的十位,我是对的吗?

2 个答案:

答案 0 :(得分:5)

  1. 调用HeapAlloc听起来不是跨平台的。 MS可以随时改变他们的实施;建议远离。 :)
  2. 它可能更有效地使用内存池,就像Loki库中的“小对象分配器”一样
  3. 堆分配,通常是通用的,通过任何实现总是很慢。分配器越“专业化”,它就越快。这使我们返回到#2点,它处理内存池(以及特定于您的应用程序使用的分配大小)。
  4. 不知道。

答案 1 :(得分:1)

  

从上面我得到的印象是HeapAlloc()/ VirtualAlloc()非常慢,以至于malloc()只是偶尔调用一次然后管理分配的内存本身要快得多。这个假设是真的吗?

OS级系统调用经过精心设计和优化,可用于管理进程的整个内存空间。使用它们为整数分配4个字节确实不是最理想的 - 通过管理库代码中的微小分配,让操作系统针对更大的分配进行优化,可以获得更好的性能和内存使用率。至少据我所知。