The CLR uses a technique known as mark-and-sweep.
As part of this technique, every object can be thought of as initially marked for collection. Then, the CLR goes through each accessible object, starting with your globals (static fields, etc.) as the roots, and clears the mark on each walkable object. It then sweeps the remaining marked objects.
Keep in mind that this "marking" is conceptual; in reality, the objects are most likely added to a collection-set.
In the case of looping self-referenced objects, no reference to the objects will be found from the application, and so the algorithm will never reach those objects to "unmark" them.