如何模拟OutOfMemory异常

20

我需要重构我的项目,以使其免受 OutOfMemory 异常的影响。

我的项目中使用了大量的集合,通过更改一个参数,我可以使程序更精确或使用更少的内存...

好的,那就是背景。我想要做的是循环运行例程:

  1. 使用默认参数运行子例程。
  2. 捕获 OutOfMemory 异常,更改参数并尝试再次运行它。
  3. 执行第 2 点,直到参数允许在不抛出异常的情况下运行子例程(通常只需要更改一次)。

现在,我想测试它。我知道,我可以自己抛出 OutOfMemory 异常,但我想模拟一些真实的情况。

所以主要问题是:
有没有办法为我的程序设置某种内存限制,在达到该限制后,OutOfMemory 异常将自动抛出?
例如,我想设置一个限制,比如整个程序最多使用 400MB 的内存,以模拟系统中可用这么多内存的情况。
这可以做到吗?

6个回答

19

看起来这个类的工作方式与我需要的相反。它实际上是检查是否有一定量的内存可用(例如,调用MemoryFailPoint(100)可以检查是否可以执行消耗100MB的操作)。我需要的是检查我的程序已经消耗了多少内存。 - Gacek

10
public void EatMemory()
{
    List<byte[]> wastedMemory = new List<byte[]>();

    while(true)
    {
        byte[] buffer = new byte[4096]; // Allocate 4kb
        wastedMemory.Add(buffer);
    }
}

除非你有12GB的内存,否则不应该需要很长时间 :)


5
Om nom nom!Windows在x86架构上限制应用程序使用2GB内存,而在64位架构上略高一些,因此12GB并不重要。 - NibblyPig
有趣的是,我运行了上面的代码,它很好地破坏了我的电脑。Windows变得完全无响应,最终我才能进入任务管理器,看到Visual Studio使用了3GB的内存。我没有收到任何异常,并且内存使用量不断增加到约3.1GB,然后跳回3GB...我有4GB的内存。 - NibblyPig
@SLC:页面文件可能保护了您免受此类问题的影响,当您注意到计算机变得缓慢时,它可能已经启动了。 - Dave
很奇怪...因为我最近处理了OOM异常情况,而页面文件完全没有帮助!它是x86。 - Nayan
如果你想要一些真正有趣的结果,你可以随时禁用页面文件。 - Aren

5

只需分配一个非常大的数组。一旦您的C#应用程序达到1.2-1.6GB的RAM使用量(通常在该范围的较低端,如果其目标是x86),您很可能会开始遇到内存不足异常。


好的,但这和我自己抛出OutOfMemory异常得到的结果是一样的。我想模拟真实情况,并使用一些小数据集进行测试(它们只占用大约400MB的内存,而不是1.6GB)。 - Gacek
最好开始构建每个长度为1GB的数组数组。您将能够相当快地复制它。 - Nayan

4
string value = new string('crazy', int.MaxValue);

1
字符串 value = new string('c', int.MaxValue); - Nicola C.
这对于一个“立即崩溃应用程序”的功能非常有效。 - Étienne Laneville
这对于“让应用程序立即崩溃”的功能非常有效。 - undefined

2
我想提出另一种看待这个问题的方式。您不必一定用尽内存,只需要监视所使用的内存量,并将其与系统总内存进行比较。也许像GC.GetTotalMemory这样的方法对于查看应用程序使用了多少内存很有用。然后这篇文章可以帮助您获取系统上可用的物理RAM总量。

好的,我甚至不需要和系统内存进行比较,我只需要知道我的程序使用了多少MB的RAM。我需要阅读一下GC的文档...谢谢! - Gacek
好的...既然你在寻找OutOfMemoryException,我就假设你想要在某个时刻耗尽内存以便调整达到最佳性能。但是,如果GC方法适用于你,那也很棒! - Dave
好吧,我想我可以使用GC方法,在达到某个限制后自己抛出异常。也许需要一些后台工作线程...我需要测试它是否可行。 - Gacek

2
模拟内存不足异常的好方法是在虚拟机(VM)中运行程序。您可以将虚拟机的最大内存分配设置为足够小的水平,从而在程序上创建内存压力并引发异常。
一些开源VM包括:QEMUxenkvm。 一个很好的商业虚拟机是VMware Fusion for Mac OS X或VMware Player for Linux/Windows。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接