解除分配不会释放Windows / C ++应用程序中的内存

时间:2008-12-15 11:49:32

标签: c++ windows winapi memory-management memory-leaks

我的Windows / C ++应用程序使用运算符new在内存中分配〜1Gb的数据并处理此数据。处理完毕后,数据将被删除。

我注意到如果我在不退出应用程序的情况下再次运行处理,则第二次调用运算符new来分配〜1Gb数据失败。

我希望Windows能够提供内存。用其他一些Win32调用等可以更好地管理吗?

5 个答案:

答案 0 :(得分:6)

我认为这不是Windows问题。检查您是否正确使用了删除或删除[]。如果您发布分配/释放内存的代码,也许会有所帮助。

答案 1 :(得分:5)

在大多数运行时环境中,从操作系统分配给应用程序的内存仍保留在应用程序中,很少返回给操作系统。释放内存块允许您从应用程序中重用该块,但不会将其释放到操作系统以使其可供其他应用程序使用。

Microsoft的C运行时库尝试通过调用_heapmin_region调用_heap_free_region或_free_partial_region将内存返回给操作系统,调用VirtualFree将数据释放到操作系统。但是,如果相应区域中的整个页面不为空,则不会释放它们。造成这种情况的常见原因是C ++容器的簿记信息和存储缓存。

答案 2 :(得分:3)

可能是由于内存碎片(实际上是地址空间碎片),其中各种因素导致您的程序地址空间没有可用的1gb连续漏洞。实际上,我怀疑你的内存管理存在错误(抱歉) - 你是否通过泄漏检测运行代码?

答案 3 :(得分:1)

这个问题几乎可以肯定是内存碎片。在32位Windows上,您可以分配的最大连续区域大约为1.1GB(因为EXE中的各种DLL会阻止更大的连续范围可用)。如果在释放内存分配(或DLL加载或内存映射文件)之后,在前一个1GB区域的中间结束,则不再有1GB区域可用于下次调用new以分配1GB。因此它会失败。

您可以使用VM Validator来显示此流程。

答案 4 :(得分:1)

由于您使用的是非常大的内存块,因此您应该考虑使用VirtualAlloc()VirtualFree(),因为它们允许您直接分配和释放页面,而无需进行交互的开销(内存和时间)与堆经理。

由于您使用的是C ++,因此值得注意的是,您可以使用placement new以这种方式在内存中构造C ++对象。