Roadmap › C# Language — Basics to Advanced › Module: Errors, Resources and Memory
Lessons in this course (38)

29. IDisposable, using and the garbage collector

Intermediate★ Must knowLesson 29 of 38

The GC frees managed memory automatically. It is generational: Gen 0 (new, collected often), Gen 1 (buffer), Gen 2 (long-lived). Objects ≥ 85,000 bytes go to the Large Object Heap.

Unmanaged resources (file handles, sockets, DB connections) must be released deterministically with IDisposable:

csharp
using (var conn = new SqlConnection(cs))      // classic using block
{
    conn.Open();
}
using var file = File.OpenRead("data.csv");   // using declaration (C# 8): disposed at end of scope
await using var stream = new FileStream(...);  // IAsyncDisposable

public sealed class Wrapper : IDisposable
{
    private readonly SafeHandle _handle;
    private bool _disposed;
    public void Dispose()
    {
        if (_disposed) return;
        _handle.Dispose();
        _disposed = true;
    }
}
  • Finalizer (~ClassName()) runs on the finaliser thread at an unknown time; only needed when you own a raw unmanaged handle. Call GC.SuppressFinalize(this) in Dispose when a finaliser exists.
  • Calling GC.Collect() manually is almost always wrong.