将几个大文件映射到内存中

时间:2012-04-24 04:47:07

标签: c++ windows-xp

在我们的应用程序中,我们必须能够将几个(即最多4个)文件映射到内存中(通过 mapViewOfFile )。很长一段时间这不是问题,但随着文件在过去几年变得越来越大,现在内存碎片阻止我们映射那些大文件(文件将大约200 MB)。如果此时没有加载其他文件,则问题可能已存在。

我现在正在寻找确保映射始终成功的方法。因此,我想在程序启动时为映射保留一块内存,因此碎片会受到更少的影响。

我的第一个方法是 HeapCreate 一个私有堆,然后我会 HeapAlloc 一个足够大的内存块来保存一个文件的映射,然后使用 MapViewOfFileEx ,带有该块的地址。因为地址必须匹配内存分配粒度。但映射仍然失败,错误代码为ERROR_INVALID_ADDRESS(487)。

接下来我用 VirtualAloc 尝试了同样的事情。我的理解是,当我传递参数MEM_RESERVE时,我就可以将该内存用于我想要的内容,例如:映射文件的视图。但我发现这是不可能的(与上面相同的错误代码),直到我再次使用 VirtualFree 完全释放整个块。因此,下一个文件将不再有保留的内存。

我已经在使用低碎片堆功能,对我们来说几乎没用。目前,重写我们的代码只能使用较小的文件视图。我还看了一下这篇文章Can address space be recycled for multiple calls to MapViewOfFileEx without chance of failure?,但没有发现任何它非常有用,并希望有其他可能性。

您有什么建议我可以做什么或我的设计可能出错? 谢谢。

1 个答案:

答案 0 :(得分:0)

嗯,MapViewOfFileEx的文档很明确:“建议的地址用于指定文件应该映射到多个进程中的同一地址。这需要所有地址空间区域都可用涉及的进程。在用于映射的区域中不能进行其他内存分配,包括使用VirtualAlloc

低碎片堆旨在防止相对较小的分配失败。即它避免了1个字节的漏洞,因此2字节分配可以保持更长时间。按32位标准,您的分配不小。

实际上,这会受到伤害。如果你真的需要它,重新实现内存映射文件。所有必要的功能都可用。使用向量异常处理程序在源代码中进行分页,并使用QueryWorkingSet确定页面是否脏。