2012-08-12 54 views
4

我们有一个应用程序,可能会分配大量的小对象(取决于用户输入)。有时候应用程序耗尽内存并且崩溃。但是,如果我们知道内存分配变得紧张,那么会存在一些优先级较低的对象,这些对象可能会被破坏,从而使我们能够正常降级用户结果。检测内存运行低前在Windows分配开始失败

在调用'new'失败之前,检测进程内存的最佳方式是什么?我们可以调用API函数,如GetProcessWorkingSetSize()GetProcessMemoryInfo(),但您如何知道何时达到给定机器的限制(例如,最大分配的80%)?

+1

除非你的硬盘快满了,这个问题是不是在释放内存的机器上的金额(因为你有虚拟磁盘上的内存),但地址空间碎片是由于这些对象和可能的内存泄漏。 – 2012-08-12 12:37:49

+0

@AlexeyFrunze在32位Windows内存分配似乎开始失败大约1.5GB。这不是内存泄漏,我们可以解释所有使用过的内存,但是我关于碎片的看法。 – snowdude 2012-08-13 09:00:38

回答

4
  • 在启动时,分配一个内存储备。
  • 然后使用set_new_handler()安装一个会检测到分配失败的钩子。
  • 当发生下列情况时:
    • 释放储备(所以你有足够的可用内存来处理)。
    • 运行你的代码,找到并释放低优先级的对象。
    • 当它完成它的工作时,尝试再次重新分配储备(下次)。
    • 最后返回让原始分配尝试重试。
+0

谢谢,好主意。 – snowdude 2012-08-13 09:01:22

0

检查答案Win32/MFC: How to find free memory (RAM) available?

您需要定期查找可用空闲内存并在某些限制下停止分配。 正如上面提到的答案中所述,您可以使用GlobalMemoryStatusEx和/或VirtualQueryEx

+0

通常不是一个好主意。见http://blogs.msdn.com/b/oldnewthing/archive/2012/01/18/10257834.aspx – 2012-08-13 05:57:04

+0

@HarryJohnston好点。但这是问题还是这个特殊的答案? – Rohan 2012-08-13 06:13:25

+0

我认为我们的问题是微妙的不同。我们不关心操作系统即将停止分配我们的程序内存时我们只想知道的全局系统资源,所以我们可以在它太迟之前做些什么。 – snowdude 2012-08-13 09:08:58

2

如果它是一个32位的进程,那么你会希望确保不要超过1.6GB,这是2.0GB的80%,这是你的进程所允许的最大值。调用GlobalMemoryStatusEx将填充结构MEMORYSTATUSEX.ullAvailVirtual,当这只有400MB可用(或更少),那么你是在你的门槛。