【问题标题】:Will Visual C++ runtime malloc / free return memory to OS?Visual C++ 运行时 malloc / free 会将内存返回给操作系统吗?
【发布时间】:2011-09-23 12:17:13
【问题描述】:

这个问题与Will malloc implementations return free-ed memory back to the system? 非常相似,但我对 Windows/Microsoft Visual Studio 的答案以及关于确切虚拟内存状态的详细信息感兴趣。

Visual C++ CRT free 会将内存返回给系统吗?关于虚拟内存分配,内存的确切状态是什么?在大内存块上做free后,块中的内存是commit,reserved,还是free?免费后打_heapmin怎么办?

【问题讨论】:

  • free 将其返回给运行时分配器。之后发生的事情是分配者的决定。有时会返回系统,有时会挂起并尝试重用。
  • 另外,MSVC 附带 CRT 的源代码,因此您可以自行检查并阅读它调用的 Win32 API 函数。
  • 您真正应该担心的是释放您 malloc 的内存并将其他堆管理留给操作系统。
  • @C Johnson:这可能适用于许多应用程序,但并非适用于所有应用程序。在我的情况下,我需要担心虚拟内存消耗,因为应用程序使用的系统组件(即 Direct3D 资源分配,但可能还有其他一些)直接使用虚拟内存操作,而不是使用 malloc/free。如果堆耗尽了虚拟内存,则会导致无法恢复的错误,因为无论我的应用程序释放多少内存,Direct3D 仍然会因为没有可用的虚拟内存而失败。

标签: c++ c visual-studio visual-studio-2010 memory-management


【解决方案1】:

查看2010的源码可以看到malloc/free直接调用HeapAlloc/HeapFreeWin32 API函数,运行时创建了一个_crtheap作为堆。因此,对于 VS 2010 和最新的 Windows 版本(Win2000、WinXP、Vista、Win 7)的答案是:

free 返回的内存返回给操作系统,但仍保持提交状态。

Heap Functions documentation 关于如何处理内存承诺如下所述:

HeapCreate 函数创建一个私有堆对象,调用进程可以使用 HeapAlloc 函数从中分配内存块。 ...如果 HeapAlloc 的请求超过了已提交页面的当前大小,则会自动从该保留空间提交其他页面,假设它的物理存储可用。提交页面后,在进程终止或通过调用 HeapDestroy 函数销毁堆之前,它们不会被取消提交。

此外,HeapCreate documentation 关于没有设置最大大小的堆的情况如下:

如果 dwMaximumSize 为 0,堆的大小可以增长。堆的大小仅受可用内存的限制。分配大于固定大小堆限制的内存块的请求不会自动失败;相反,系统调用 VirtualAlloc 函数来获取大块所需的内存。需要分配大内存块的应用程序应将 dwMaximumSize 设置为 0。

我没有找到任何可以说明使用 VirtualAlloc 分配的块在释放时是否以特殊方式处理的信息,可能需要进行实验才能知道这一点。

至于_heapmin,VS 2010 什么都不做,因为它只调用HeapCompact,并且 CRT 堆没有关闭空闲时自动合并。因此,_heapmin 的文档似乎是错误的,很可能是某个旧版本运行时的遗留物。

【讨论】:

    【解决方案2】:

    不,它不会将内存返回给“系统”。 _heapmin 只释放空的整个页面,并且通常没有什么效果。它不会在页面之间打乱数据。因此,这取决于堆内存的释放位置,以及 free() 和 _heapmin 的组合是否实际上会减少正在使用的页面数。另请注意,VS 使用不同的堆进行调试和发布。

    如需更多控制,请参阅 HeapCreate()/HeapAlloc() 等 API。

    【讨论】:

      猜你喜欢
      • 2015-03-12
      • 2021-04-05
      • 1970-01-01
      • 1970-01-01
      • 2015-08-08
      • 2019-04-07
      • 2011-06-05
      相关资源
      最近更新 更多