4

我的 Windows/C++ 应用程序使用操作员在内存中分配 ~1Gb 的数据new并处理这些数据。处理后数据被删除。

我注意到,如果我在不退出应用程序的情况下再次运行处理,则对操作员的第二次调用以new分配 ~1Gb 的数据会失败。

我希望 Windows 能够将内存返回。这可以通过其他一些 Win32 调用等以更好的方式进行管理吗?

4

5 回答 5

6

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

于 2008-12-15T11:53:30.247 回答
5

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

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

于 2008-12-15T11:55:00.120 回答
3

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

于 2008-12-15T11:54:48.933 回答
1

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

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

于 2008-12-15T20:22:28.877 回答
1

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

您可以使用VM Validator可视化此过程。

于 2010-04-10T20:51:02.277 回答