The System.OutOfMemoryException – Exception of type 'System.OutOfMemoryException' was thrown
is a runtime exception in C# that occurs when the application runs out of memory. This typically happens when:
- The application allocates too much memory (e.g., large arrays, collections, or objects).
- There is a memory leak (e.g., objects are not properly disposed of or garbage collected).
- The system does not have enough available memory to allocate.
Here’s how you can troubleshoot and fix this issue:
1. Optimize Memory Usage
- Avoid allocating large objects or collections unnecessarily. Use smaller data structures or split large operations into smaller chunks. Example:
int[] largeArray = new int[1000000000]; // Error: Allocates too much memory
Fix:
int[] smallerArray = new int[1000000]; // Use a smaller array
2. Use IDisposable
and using
Statements
- Ensure that objects implementing
IDisposable
(e.g., file streams, database connections) are properly disposed of usingusing
statements or explicit calls toDispose()
. Example:
var stream = new System.IO.FileStream("file.txt", System.IO.FileMode.Open);
// Use the stream
// Error: Stream is not disposed, leading to memory leaks
Fix:
using (var stream = new System.IO.FileStream("file.txt", System.IO.FileMode.Open))
{
// Use the stream
} // Stream is automatically disposed
3. Avoid Memory Leaks
- Ensure that objects are not unintentionally kept alive by strong references (e.g., event handlers, static fields). Example:
public class EventSource
{
public event EventHandler Event;
}
public class EventSubscriber
{
public EventSubscriber(EventSource source)
{
source.Event += OnEvent; // Event handler keeps subscriber alive
}
private void OnEvent(object sender, EventArgs e) { }
}
Fix:
public class EventSubscriber
{
public EventSubscriber(EventSource source)
{
source.Event += OnEvent;
}
private void OnEvent(object sender, EventArgs e) { }
public void Unsubscribe(EventSource source)
{
source.Event -= OnEvent; // Unsubscribe to avoid memory leaks
}
}
4. Use Weak References
- Use
WeakReference
for objects that can be recreated or are not critical to keep in memory. Example:
var largeObject = new LargeObject();
var weakReference = new WeakReference(largeObject);
if (weakReference.IsAlive)
{
largeObject = (LargeObject)weakReference.Target; // Recreate if needed
}
5. Monitor Memory Usage
- Use tools like Visual Studio Diagnostic Tools, Performance Profiler, or third-party memory profilers to monitor and analyze memory usage. Example:
- Use the Visual Studio Diagnostic Tools to identify memory leaks or excessive allocations.
Example of Correct Code
using System;
using System.IO;
public class Program
{
public static void Main(string[] args)
{
// Example 1: Optimize memory usage
int[] smallerArray = new int[1000000]; // Use a smaller array
Console.WriteLine("Array allocated");
// Example 2: Use 'using' statement for disposable objects
using (var stream = new FileStream("file.txt", FileMode.Open))
{
// Use the stream
Console.WriteLine("File stream opened");
} // Stream is automatically disposed
// Example 3: Avoid memory leaks
EventSource source = new EventSource();
EventSubscriber subscriber = new EventSubscriber(source);
subscriber.Unsubscribe(source); // Unsubscribe to avoid memory leaks
}
}
public class EventSource
{
public event EventHandler Event;
}
public class EventSubscriber
{
public EventSubscriber(EventSource source)
{
source.Event += OnEvent;
}
private void OnEvent(object sender, EventArgs e) { }
public void Unsubscribe(EventSource source)
{
source.Event -= OnEvent; // Unsubscribe to avoid memory leaks
}
}