The Common Language Runtime provides several services to managed applications, such as the Garbage Collector (GC). The developer is responsible for allocating memory for reference types on the managed heap using the new operator. However, the Garbage Collector is responsible for freeing managed objects on the managed heap.
The managed heap is organized in generations: Generation 0, 1, and 2. By partitioning the heap into generations, partial garbage collections can be performed to avoid the overhead of collecting the entire heap. There is also the Large Object Heap, which holds large objects. Because large objects typically live longer, this avoids the expense of promoting large objects between generations.
Garbage collection is initiated when a new allocation would cause the memory threshold for Generation 0 to be exceeded. A full garbage collection is a Generation 2 collection, which also collects Generations 0 and 1. Conversely, a garbage collection of Generation 1 also collects Generation 0. Finally, a collection of Generation 0, which is a minimum collection, only collects that generation. Garbage collection is performed on the Large Object Heap during a full garbage collection. Memory for objects on the Large Object Heap can be reclaimed. However, the Large Object Heap is not compacted.
There is sometimes a disparity between the size of a native resource and a managed wrapper class for that resource. Use the GC.AddMemoryPressure and GC.RemoveMemoryPressure methods to account for the differences.
Non-deterministic garbage collection occurs when additional memory is needed for Generation 0, which is somewhat unpredictable. This can delay the cleanup of resources associated with unreachable objects. For the deterministic cleanup of resources, implement the IDisposable interface. The IDisposable interface has a single method—the Dispose method. Call the Dispose method on a disposable object to immediately clean up related resources. If the base and derive classes are both disposable, implement the dispose pattern.
Use the CLR Profiler to diagnose memory issues in managed applications. The CLR Profiler offers a variety of graphs and reports that detail the current or historic state of the managed heap of a managed application. This information can be helpful in resolving difficult memory problems.