Garbage Collection and IDisposable
Short, interview-ready summary.
Memory hook
"GC = reclaims heap objects with no references; IDisposable = release unmanaged or scarce resources explicitly"
Garbage collector (GC)
- Heap — reference types (objects) live here
- GC — finds objects no longer referenced and reclaims memory
- Non-deterministic — you don’t control when it runs
- Generations — Gen0 (short-lived), Gen1, Gen2 (long-lived); Gen0 collected most often
What GC does not do
- It does not free unmanaged resources (handles, native memory, file descriptors)
- It does not run at a predictable time
IDisposable and using
"IDisposable = contract for releasing resources; using = call Dispose automatically"
public interface IDisposable
{
void Dispose();
}
using statement (dispose at end of scope)
using (var stream = File.OpenRead("file.txt"))
{
// use stream
} // Dispose() called here
// using declaration (C# 8+)
using var stream = File.OpenRead("file.txt");
// Dispose at end of enclosing scope
Implementing IDisposable (simple pattern)
public class MyResource : IDisposable
{
private bool _disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
if (disposing)
{
// release managed resources
}
// release unmanaged resources
_disposed = true;
}
}
- Dispose(bool disposing) — disposing true = from Dispose(); false = from finalizer (if any)
- GC.SuppressFinalize(this) — skip finalizer when Dispose was called
Finalizer (destructor)
~MyResource();
{
Dispose(false);
}
- Runs when GC collects the object (non-deterministic)
- Use only as backup for unmanaged resources if caller didn’t call Dispose
- Finalizers are expensive; prefer IDisposable + using
When to use IDisposable
- File handles, streams, DB connections
- Native/unmanaged resources
- Event subscriptions (to unsubscribe and avoid leaks)
- Any scarce or unmanaged resource that must be released
Interview one-liner
"GC reclaims unreferenced objects on the heap. For unmanaged or scarce resources, implement IDisposable and call Dispose (or use using). Finalizers are a fallback for unmanaged resources only; prefer Dispose + using."
Cheat sheet
GC = heap, non-deterministic, generations
IDisposable = release resources
using = auto Dispose
Implement Dispose(bool); SuppressFinalize in Dispose
Finalizer = last resort for unmanaged