tags:

views:

435

answers:

5

I'm aware that the .net garbage collector detects cyclic references but I was wondering whether cyclic references may cause objects to stay longer than necessary.

I have a cyclic reference in my ASP.NET app (an intended one for performance related reasons), can I get away with that?

Regards

A: 

The Java GC can detect cycles and deal with them. I'd bet that the C# GC can as well.

duffymo
+10  A: 

It doesn't take the CLR any longer to remove a cyclic reference than a non-cyclic reference. The CLR uses a combination of techniques to garbage collect. The quick version though is it starts with all rooted objects (objects on the stack, or held with a strong GC handle). Any object that is reachable from these objects is alive. Anything else will be collected. A cyclic reference won't affect the results of this algorithm other than the CLR has to make sure to check for them and not walk in circles

JaredPar
+3  A: 

It doesn't need to detect cycles, because in the algorithm it uses, cycles are simply not an issue.

If there is a path from a root (a variable on the stack, or a static variable, basically, because these are known to be live, and must not be GC'ed) to an object, then that object must be live too, and will not get GC'ed.

If there is no path, then the object is dead and can be GC'ed safely. Cycles simply don't matter. So no, cycles won't make a difference in objects lifetime.

jalf
+1  A: 

Basically if any statics, local variables, parameters, or member variables references an object it is not available for garbage collection. It doesn't really matter if cyclic references are present or not. Either the cycle is referenced, in which cases it isn't collected or it isn't referenced in which case the entire cycle may be collected.

If a type implements a finalizer it will survice collection(s) until its finalizer has run.

Brian Rasmussen
A: 

The GC will collect any object that is not referenced by a root object. Root objects are typically objects referenced by all appdomains (i.e. loaded assemblies/type objects), global and static object references, all object references on each thread's respective stack plus any object reference currently loaded into a CPU register.

At collection time, the GC walks the references of all known root objects and marks any object it finds along the way as "in use". When done, any objects not marked can be safely collected.

So if none of your objects are referenced (directly or indirectly) by a root object, it does not matter if there are cyclic references. They will all be eligible for collection regardless. I say eligible, because the GC uses three different strategies for collecting eligible objects, and for performance reasons only one of those collects all eligible objects when run.

Normally you won't have to think about this, it just works. But there is a lot more to garbage collection and you still need to understand the fundamentals of it in order to understand memory management and write bug free code that does not leak resources etc. Therefore its something every .NET developer should take a look at. Here are a few resources that explain more about how the CLR does garbage collection.

MSDN - Garbage Collector Basics and Performance Hints (Rico Mariani)

MSDN Magazine - Garbage Collection (Part 1): Automatic Memory Management in the Microsoft .NET Framework (Jeffrey Richter)

MSDN Magazine - Garbage Collection (Part 2): Automatic Memory Management in the Microsoft .NET Framework (Jeffrey Richter)

Mahol25