C# System.OutOfMemoryException
While programming for my web app the other day, my application threw an System.OutOfMemoryException when initializing a list of objects. To me this seemed pretty much impossible because my machine has 4GB RAM. Specifically the error happened when I tried to add an existing collection to a new list. For example:
List newShapes = new List(selectedShapes);
My original thought was that this assignment shouldn't allocate much memory since the shapes from my list should already exist inside memory. The Shape class is a complex object and I was trying to assign about 25,000 items to the new list at once. We should also note that the total size of all Shapes in the application come from a database that is only about 250MB in size. At first I was stumped and had no idea what may be causing the System.OutOfMemoryException.
What happened
- If you are running a 32 bit Windows, you won't have all the 4GB accessible, only 2GB per object array. This is a limitation of the .NET framework. (This happened to be my issue, as my shape array was greater than 2GB after debugging..)
- Don't forget that the underlying implementation of
List
is an array. If your memory is heavily fragmented, there may not be enough contiguous space to allocate yourList
, even though in total you have plenty of free memory.
Solutions
- If you are running on 64 bit Windows and you have enough free memory, ensure that the platform target is set correctly in the project properties > build properties.
- If you are using .NET 4.5 or greater you can add this line to the runtime section of your App.Config:
<runtime>
<gcallowverylargeobjects enabled="true"></gcallowverylargeobjects>
</runtime>
Tips when debugging a C# System.OutOfMemoryException
-
Remember that data stored in the database compared to in memory is very different. Use this C# snippet to observe how much your memory is changing as you load the object(s) into memory.
GC.GetTotalMemory()
Common causes of C# System.OutOfMemoryException
-
Initializing an array which is not large enough, ensure the array size is correct! This is by far the most common cause of this exception.
-
Reading very large data sets into memory, as demonstrated in the example above.
-
Having too many active sessions or storing too much data in session state.
-
Applying a complex regex (regular expression) to a large file or string.
-
Downloading, streaming or uploading large files.
-
You are calling the StringBuilder.Insert method and are repeatedly concatenating strings.
-
You are not implementing the Implementing a Dispose method when dealing with unmanaged resources, and your app is leaking.
-
You are storing very large sets of data in memory. An example could be querying large database data sets via LINQ in memory.