Start here. This is the direct spoken answer to practice first.
Why this question matters
The garbage collector reclaims unreachable managed objects, not objects the business has finished using. One accidental path from a long-lived root can retain a much larger graph and make memory rise even though allocation and collection are working normally.
An object remains alive while the garbage collector can reach it from a root. Roots include active stack and register references, static fields, runtime handles, and other runtime-owned references. The GC follows fields from those roots through the object graph and reclaims objects outside that graph. Therefore a static dictionary, event publisher, queued callback, or singleton can retain request data long after the request ends. Setting an unrelated local to null or forcing a collection does not break the real path.