views:

387

answers:

5

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?

+5  A: 

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
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
That won't work reliably on 64bit.
Thorsten79
Better, start building array of arrays with 1GB length each. You'll be able to reproduce it fairly quickly.
Nayan
+1  A: 
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
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.
SLC
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.
SLC
@SLC: page file probably protected you against that, which probably kicked in when you noticed that your PC slowed to a crawl.
Dave
That's strange... because I recently worked on OOM exception case and page file did not help at all!! It was x86.
Nayan
You can always disable your pagefile if you want some REAL fun results.
Aren
+1  A: 

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.

Dave
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
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
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
+10  A: 

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 you input parameters accordingly.

AlfredBr
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
+1  A: 

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