How does garbage collection and scoping work in C#? [duplicate]

I'm learning C# coming from python and wish to know how the C# garbage collector works - I found that I understood a lot more about python once I figured out what it was doing behind the scenes, and wish to avoid making the sort of noob errors I made at first when learning python.

I've not been able to find any good clear explanations of when an item is garbage collected and am left with questions such as

  1. "What happens to an object when its last reference passes out of scope?" Does that object get garbage collected or is it still there when you pass back into the scope in which it was defined?
  2. "At what point is the number of refernces decremented?" Leading me to wonder whether it even uses reference counting or some other technique...

Answers to these, or even better a clear consise overview of what's actually going on will win cookies (or upvotes), and even better if your answer compares it to the python way of doing things. I'm not interested in which is better, just the details. Also answers on my original post on programmers.stackexchange would be much appreciated...


The dotnet GC engine is a mark-and-sweep engine rather than a reference-counter engine like you're used to in python. The system doesn't maintain a count of references to a variable, but rather runs a "collection" when it needs to reclaim RAM, marking all of the currently-reachable pointers, and removing all the pointers that aren't reachable (and therefore are out of scope).

You can find out more about how it works here:
http://msdn.microsoft.com/en-us/library/ee787088.aspx

The system finds "reachable" objects by starting at specific "root" locations, like global objects and objects on the stack, and traces all objects referenced by those, and all the objects referenced by those, etc., until it's built a complete tree. This is faster than it sounds.


At some indeterminate point in time after the last reference to an object disappears, the object will be collected.

The second part of your first question doesn't make sense.
If you can get back into the scope in which an object was defined (eg, a lambda expression), there is obviously still a reference.

The GC does not use reference counting at all.
Rather, it uses a mark-and-sweep algorithm.


Garbage collection is not triggered by references going out of scope. Garbage collection is usually triggered when allocating storage for new objects - specifically when generation zero's budget is exhausted. I.e. there may be a significant delay between when objects are eligible for garbage collection and when they are actually collected. As others have already pointed out, the CLR doesn't use reference counting. Instead it employs a mark and sweep approach.

A good source of information on all the details about how garbage collection works is Jeffrey Ricther's book CLR via C#. The book goes into great detail about how the heap is partitioned and how garbage collection works. Highly recommended if you're interested in .NET implementation details.