至少在Windows下有多少堆软件

时间:2011-07-10 09:41:44

标签: c++ memory

我发现C-runtime有自己的堆(以及windows HeapWalk下的所有Heap API)。关于我以前的知识,我似乎有点麻烦,看起来这个过程实际上有几个堆而不仅仅是一个。这样对吗 ?如果是这样的话,为什么需要几个堆?

5 个答案:

答案 0 :(得分:7)

Windows进程通常至少有3个堆:

  • 默认进程堆。 GlobalAlloc()从中分配,主要由Windows使用
  • COM堆。 CoTaskMemAlloc()和SysAllocString()从中分配,由任何COM服务器使用
  • CRT堆。 new运算符和malloc()函数从中分配。

拥有多个CRT堆并不罕见,使用/ MT构建的任何DLL都有自己的CRT副本,从而获得自己的堆。我没想到只从单一堆中分配的确切原因对我来说是模糊的。

GetProcessHeaps()函数可用于迭代过程中的所有堆。


更新:黑暗部分有点不受影响。从VS2012开始,CRT现在从默认进程堆中分配第一个项目符号。请记住,这不会追溯性地更改未重建的旧DLL上的行为。

答案 1 :(得分:3)

堆只是一个数据结构。您可以从C运行时,O / S,第三方获得任意数量的内容,也可以自己编写。

为什么你需要不止一个?不同的堆可能擅长不同的东西。一个人可能擅长分配小对象,一个善于分配大对象。一个人可能擅长检测堆分配错误,另一个可能非常快,但如果误用可能会导致程序崩溃。等等。

答案 2 :(得分:2)

在Windows API中有一个堆的概念并不是太广为人知(从现在的其他答案来判断)。说实话,我也不太了解,但这里是:

Windows API允许您创建不同的堆,这意味着总数将取决于您正在运行的应用程序,堆中的内存分配器的行为可以稍微更改以适应不同的使用模式(搜索低碎片堆)。最重要的区别是从一个堆获取的内存必须释放到同一个堆中。在大多数程序中,您不会直接看到不同的堆或与之交互,因此您不必过于担心。

请记住,当库提供Release方法时,您应该使用它而不是delete,因为从库中获取的内存可能来自不同的堆。

答案 3 :(得分:1)

进程有一个可以扩展的堆区域,具体取决于需要多少空间。

实际发生的是堆栈增长并且堆增长,只要存在虚拟内存,就可以扩展堆栈和堆。您看到的不同堆可能是内存映射等不同的映射堆范围。

答案 4 :(得分:0)

堆扩展到更高的内存地址,而堆栈则向更低的地址增长。程序可用的堆量取决于分配的堆栈数量。堆栈包含函数的堆栈帧(局部变量,参数和注册表指针),而堆是用malloc手动分配的。 AFAIK,这是一个没有多线程的单个程序(即进程)的情况。