Mid-level (2-5 years)C#

How does garbage collection work in C# and when should you use IDisposable?

Quick answer

The .NET garbage collector automatically frees managed objects that are no longer reachable, organising them into generations 0, 1 and 2 so short-lived objects are collected cheaply, and IDisposable is used to release unmanaged resources such as files and connections promptly.

New objects start in generation 0. Objects that survive a collection are promoted to generation 1 and then to generation 2. Collecting generation 0 is fast and frequent, while generation 2 collections are expensive. Objects of roughly 85,000 bytes or more go on the large object heap, which is collected with generation 2, so allocating many large temporary arrays can hurt performance.

The GC knows about memory, not about files, sockets or database connections. Types that hold those implement IDisposable, and you should wrap them in a using statement so the resource is released deterministically, instead of waiting for a finalizer. Common memory problems are not classic leaks but objects kept reachable by static fields, event handlers that are never unsubscribed, and caches without limits.

await using var connection = new SqlConnection(connectionString);
await connection.OpenAsync();
// connection is disposed (and returned to the pool) at the end of the scope

Key points

  • Generational GC: gen 0, 1, 2 and the large object heap
  • Dispose releases unmanaged resources; GC releases memory
  • Static references and event handlers keep objects alive

Questions interviewers ask next

  • What is the difference between Dispose and a finalizer?
  • What is Span<T> and why does it reduce allocations?