2

我有 2GB RAM 并运行内存密集型应用程序并进入低可用物理内存状态并且系统没有响应用户操作,例如打开任何应用程序或菜单调用等。

如何触发或告诉系统将内存交换为页面文件并释放物理内存?我正在使用 Windows XP。

如果我在 4GB RAM 机器上运行相同的应用程序,情况并非如此,系统响应良好。在被可用物理内存阻塞后,系统会自动交换到页面文件并释放物理内存,不如 2GB 系统那么糟糕。

为了克服这个问题(在 2GB 机器上),尝试将内存映射文件用于由应用程序分配的大型数据集。在这种情况下,应用程序(进程)的虚拟内存很好,但系统缓存很高,并且与上述相同的问题是物理内存较少。

即使内存映射文件未映射到进程虚拟内存系统缓存也很高。为什么???!!!:(

任何帮助表示赞赏。谢谢。

4

3 回答 3

1

正如我认为您在帖子中暗示的那样,响应时间缓慢可能至少部分是由于系统延迟,而操作系统将内存内容写入页面文件以为物理内存中的其他进程腾出空间。

显而易见的解决方案(可能不实用)是在应用程序中使用更少的内存。我会假设这不是一个选项,或者至少不是一个简单的选项。另一种方法是尝试主动将数据刷新到磁盘,以持续保持可用的物理内存供其他应用程序运行。您可以使用GlobalMemoryStatusEx找到机器上的总内存。GetProcessMemoryInfo将返回有关您自己的应用程序内存使用情况的当前信息由于您说您正在使用内存映射文件,因此您可能需要另外考虑这一点。例如,我相信PageFileUsage从该 API 返回的信息不会包含有关您自己的内存映射文件的信息。

如果您的应用程序正在监视使用情况,您可以使用FlushViewOfFile主动将数据从内存强制写入磁盘。还有一个 API (EmptyWorkingSet),我认为它会尝试将尽可能多的脏页写入磁盘,但这似乎很可能会严重损害您自己的应用程序的性能。虽然,它在您知道您的应用程序进入某种空闲状态的情况下可能很有用。

最后,另一个可能有用的 API 是SetProcessWorkingSetSizeEx。您可以考虑使用此 API 来提示应用程序工作集大小的上限。这可能有助于为其他应用程序保留更多内存。

编辑:这是另一个明显的声明,但我之前忘了提。这对您来说也可能不实用,但考虑到您遇到 32 位限制,您可能会做的最好的事情之一就是将您的应用程序构建为 64 位并在 64 位操作系统上运行(并在机器上增加一点内存)。

于 2010-05-12T00:10:30.273 回答
1

如果您使用内存映射文件的数据访问模式是顺序的,则通过在打开基础文件时指定 FILE_FLAG_SEQUENTIAL_SCAN 标志,您可能会获得更好的页面回收。如果您的数据模式以随机顺序访问映射文件,这将无济于事。

您应该考虑减小地图视图的大小。这就是所有内存实际消耗和缓存的地方。由于您似乎需要处理大于可用的连续空闲物理内存的文件,因此您可能比虚拟内存页面交换器做得更好,因为您比虚拟内存更了解如何使用内存内存管理器可以。如果可能,请尝试调整您的设计,以便您可以使用较小的视图对大文件的某些部分进行操作。

即使您无法摆脱对整个基础文件范围的完全随机访问的需要,根据需要拆除并重新创建视图以将视图移动到文件的部分可能仍然是有益的下一步操作需要访问。如果您的数据访问模式在继续之前倾向于围绕文件的某些部分聚集,那么您不需要经常移动视图。拆除并重新创建视图对象会受到打击,但由于拆除视图也会释放与该视图关联的所有缓存页面,因此您可能会看到性能的净收益,因为较小的视图会显着降低内存压力和页面交换系统范围。尝试根据已安装的系统 RAM 的一部分设置视图的大小,并根据文件处理的需要移动视图。视图越大,移动它所需的次数就越少,但它消耗的 RAM 越多,可能会影响系统响应能力。

于 2010-05-12T00:50:50.703 回答
0

好吧,听起来您的程序需要超过 2GB 的工作集。

现代操作系统旨在始终将大部分 RAM 用于某些事情,只保留相当少量的空闲空间,以便可以立即将其分发给需要更多 RAM 的进程。其余的用于保存最近使用过的内存页和缓存的磁盘块;最近未使用的任何内容都被刷新回磁盘以补充空闲页面池。简而言之,不应该有太多可用的物理内存。

使用普通内存分配和内存映射文件之间的主要区别在于,当必须将数据从内存中调出时,数据将被存储在何处。它不一定对何时将内存分页产生任何影响,并且对分页所需的时间几乎没有影响。

您看到的真正问题可能不是您的可用物理内存太少,而是分页率太高。

我的建议是尝试减少程序所需的存储量,看看是否可以增加引用的局部性以减少所需的分页量。

于 2010-05-12T01:08:05.600 回答