20

I need to refactor my project in order to make it immune to OutOfMemory exception.

There are huge collections used in my project and by changing one parameter I can make my program to be more accurate or use less of the memory...

OK, that's the background. What I would like to do is to run the routines in a loop:

  1. Run the subroutines with the default parameter.
  2. Catch the OutOfMemory exception, change the parameter and try to run it again.
  3. Do the 2nd point until parameters allow to run the subroutines without throwing the exception (usually, there will be only one change needed).

Now, I would like to test it. I know, that I can throw the OutOfMemory exception on my own, but I would like to simulate some real situation.

So the main question is:
Is there a way of setting some kind of memory limit for my program, after reaching which the OutOfMemory exception will be thrown automatically?
For example, I would like to set a limit, let's say 400MB of memory for my whole program to simulate the situation when there is such an amount of memory available in the system.
Can it be done?

Gacek
  • 10,184
  • 9
  • 54
  • 87

6 Answers6

19

This looks like a job for...System.Runtime.MemoryFailPoint.

http://msdn.microsoft.com/en-us/library/system.runtime.memoryfailpoint.aspx

I think the example in the link fits your situation. Set the MemoryFailPoint to whatever level you need and then catch the InsufficientMemoryException and adjust your input parameters accordingly.

AlfredBr
  • 1,281
  • 13
  • 25
  • It seems that this class works quite opposite to what I need. It actually checks if certain amount of memory is available (for example, calling `MemoryFailPoint(100)` one can check if the operation that consumes 100MB can be executed. What I need is to check how much of memory my program already consumed. – Gacek May 06 '10 at 18:18
10
public void EatMemory()
{
    List<byte[]> wastedMemory = new List<byte[]>();

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

Shouldn't take long unless you've got 12gb of ram :)

Aren
  • 54,668
  • 9
  • 68
  • 101
  • 5
    Om nom nom! Windows limits applications to 2GB of memory on x86 and I think it's slightly higher on 64bit, so 12GB won't matter. – NibblyPig May 06 '10 at 15:39
  • Interesting, I ran the above code, and it buggered up my PC nicely. Windows became utterly unresponsive, and eventually I got to the task manager to see Visual STudio using 3GB of memory. I didn't get any exceptions, and memory usage kept creeping up to about 3.1GB then jumping back to 3GB... I have 4GB ram. – NibblyPig May 06 '10 at 15:46
  • @SLC: page file probably protected you against that, which probably kicked in when you noticed that your PC slowed to a crawl. – Dave May 06 '10 at 15:52
  • That's strange... because I recently worked on OOM exception case and page file did not help at all!! It was x86. – Nayan May 06 '10 at 16:12
  • You can always disable your pagefile if you want some REAL fun results. – Aren May 07 '10 at 00:05
5

Just allocate a very large array. You'll most likely start getting out of memory exceptions once your C# application reaches 1.2-1.6GB of RAM usage (usually on the lower side of that range, provided its targetting x86).

Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • OK, but it's the same that I can get by throwing OutOfMemory exception on my own. I want to simulate real situation and test it using some small datasets (that consume about 400MB of ram instead of 1.6GB) – Gacek May 06 '10 at 15:40
  • Better, start building array of arrays with 1GB length each. You'll be able to reproduce it fairly quickly. – Nayan May 06 '10 at 16:22
4
string value = new string('crazy', int.MaxValue);
2

I'd like to suggest another way of looking at this. You don't necessarily have to run out of memory. You just need to monitor the amount of memory used, and compare it to the total system memory. Perhaps something like GC.GetTotalMemory will be useful here to see how much memory your application is using. Then perhaps this article will help with getting the total amount of physical RAM available on your system.

Community
  • 1
  • 1
Dave
  • 14,618
  • 13
  • 91
  • 145
  • Well, I even don't need to compare it with system memory, I just need to know how much MB of RAM my program used. I need to read the doc for GC... thanks! – Gacek May 06 '10 at 15:47
  • ok... well since you were looking for OutOfMemoryException, I assumed you wanted to run out at some point for the purposes of tuning for maximum performance. But hey, if the GC methods work for you, cool! – Dave May 06 '10 at 15:51
  • Well, I guess I can use the GC methods and throw the exception on my own after reaching some limit. Maybe some background worker... I need to test if it would work. – Gacek May 06 '10 at 15:55
2

A good way to simulate an out-of-memory exception is to run the program in a virtual machine (VM). You can set the maximum memory allocation for the virtual machine to a level that is small enough to create memory pressure on your program and provoke the exception.

A few open source VMs are: QEMU, xen, and kvm. A good commercial virtual machine is VMware Fusion for Mac OS X or VMware Player for Linux/Windows.

ali01
  • 184
  • 8