The OutOfMemoryException
in C# is a runtime error that occurs when your program runs out of available memory. This doesn’t always mean your computer is out of RAM — it often means your application is trying to use more memory than allowed, or it’s not releasing memory correctly.
It’s a common issue in large or poorly optimized applications, and it can usually be fixed with some careful coding practices. Don’t worry — this guide will walk you through understanding and solving it.
What Causes This Error?
Here are a few common causes:
1. Loading Large Files into Memory
Reading an entire large file into memory (like a multi-GB log or image) at once can easily exceed available memory.
string data = File.ReadAllText("hugefile.txt");
2. Creating Massive Data Structures
Building large lists, arrays, or dictionaries without limiting their size can lead to memory exhaustion.
List<int[]> bigList = new List<int[]>();
for (int i = 0; i < 1000000; i++)
{
bigList.Add(new int[10000]);
}
3. Memory Leaks
Not disposing of unmanaged resources (like file handles or database connections) properly can lead to memory bloat over time.
4. Infinite Loops that Allocate Memory
A loop that continually adds to a list or string without breaking will eventually consume all memory.
How to Fix It
Fix 1: Process Large Files in Chunks
Instead of reading everything at once, read and process files line-by-line.
foreach (string line in File.ReadLines("hugefile.txt"))
{
// Process each line here
}
Why this works: You only keep a small portion of the file in memory at any time.
Fix 2: Use Streams and Buffers
For binary data like images or media files, use FileStream
with a buffer.
using (FileStream fs = new FileStream("largefile.bin", FileMode.Open))
{
byte[] buffer = new byte[1024];
int bytesRead;
while ((bytesRead = fs.Read(buffer, 0, buffer.Length)) > 0)
{
// Process buffer here
}
}
Why this works: It limits memory usage to the buffer size.
Fix 3: Dispose Unused Objects
Use using
blocks and dispose objects manually if needed.
using (var connection = new SqlConnection(connectionString))
{
connection.Open();
// Use connection
}
Why this works: Ensures timely release of resources, reducing memory load.
Fix 4: Break Memory-Hungry Loops
Double-check loops that allocate memory and ensure they terminate or release data.
while (condition)
{
// Ensure memory allocation is justified and finite
}
Real Example
Problematic Code
List<byte[]> images = new List<byte[]>();
for (int i = 0; i < 100000; i++)
{
images.Add(File.ReadAllBytes($"image_{i}.jpg"));
}
Fixed Version
for (int i = 0; i < 100000; i++)
{
byte[] imageData = File.ReadAllBytes($"image_{i}.jpg");
// Process imageData here, then discard or overwrite it
}
Why this works: Avoids storing all image data in memory at once.
Tips to Prevent This Error
- Use
using
statements: Automatically dispose of streams and database connections. - Limit collection sizes: Set maximum bounds for arrays and lists.
- Profile memory usage: Use tools like Visual Studio’s Diagnostic Tools or JetBrains dotMemory.
Conclusion
The OutOfMemoryException
in C# can be alarming, but it usually signals an opportunity to optimize your code. By processing data in chunks, managing memory carefully, and avoiding common traps like infinite memory loops, you can keep your programs running smoothly.
Keep this guide handy and remember — clean, memory-efficient code is just a few habits away.