我目前正在研究Windows下的 malloc()
实现 . 但在我的研究中,我偶然发现了困扰我的事情:
首先,我知道在API级别,Windows主要使用 HeapAlloc()
和 VirtualAlloc()
调用来分配内存 . 我从here收集 malloc()
的Microsoft实现(包含在CRT中的那个 - C运行时)基本上调用 HeapAlloc()
用于块> 480字节,否则管理用 VirtualAlloc()
分配的特殊区域用于小分配,以防止碎片 .
那一切都很好,很好 . 但是还有 malloc()
的其他实现,例如nedmalloc,声称比微软的 malloc
快了125% .
所有这些让我想到了一些事情:
-
为什么我们不能只为小块调用
HeapAlloc()
?在碎片方面表现不佳(例如通过"first-fit"而不是"best-fit")? -
Actually, is there any way to know what is going under the hood of the various API allocation calls? That would be quite helpful.
-
是什么让
nedmalloc
比微软malloc
快得多? -
从上面看,我得到的印象是
HeapAlloc()
/VirtualAlloc()
非常慢,以至于malloc()
只是偶尔调用一次然后管理分配的内存本身要快得多 . 这个假设是真的吗?或者是因为碎片而需要malloc()
"wrapper"?人们会认为像这样的系统调用会很快 - 或者至少会有一些想法被放入其中以使它们有效 . -
If it is true, why is it so?
-
平均而言,典型的
malloc
调用执行了多少(一个数量级)的内存读/写(可能是已分配段数的函数)?我会直观地说它是一个普通程序的十位,我是对的吗?
2 回答
OS级系统调用经过精心设计和优化,可用于管理进程的整个内存空间 . 使用它们为整数分配4个字节确实不是最理想的 - 通过管理库代码中的微小分配,并让操作系统针对更大的分配进行优化,可以获得更好的性能和内存使用率 . 至少据我所知 .
调用HeapAlloc听起来不是跨平台的 . MS可以随时改变他们的实施;建议远离 . :)
它可能更有效地使用内存池,就像Loki库与"small object allocator"一样
堆分配,通常是通用的,通过任何实现总是很慢 . 分配器越多,它就越快 . 这使我们返回到#2点,它处理内存池(以及特定于您的应用程序使用的分配大小) .
不知道 .