How smart is Garbage Collection when it comes to nested references?
Take this code for example:
Public Class SomeClass Private m_SomeOtherClass(Me) End Class
I know that GC works by looking at how many references remain, and any object without any references ends up getting dumped. So in this case, where there’s a reference coming from a member variable, is that a memory leak waiting to happen (unless you implement IDisposable, etc)?
Right now I’m assuming that the GC is smart enough for this, since it could probably check to see if any references are coming from the object itself, and just not count them towards the reference count. But I thought I would dig a little.
Basic answer: It’s not a problem.
I’ve heard this kind of question before and it stems from a confusion with Reference Counting, where circular referencing does pose a problem.
The .NET collector doesn’t count references, it just scans and flags referenced objects. Those flags also prevent it from going into a loop. This is a very simple and virtually foolproof mechanism. The system doesn’t need to count or track inbound references, so there is zero overhead for shortlived references. But you have to keep an eye on where references exist, a common problem are objects that subscribe to events. The event keeps a reference, so you need to unsubscribe before the subscribing object can be reclaimed. Another benefit of GC is that the logic also works in reverse: whenever your code has access to a reference that reference is guaranteed to be valid, simply because that reference exists.
Reference counting requires the compiler to inject code every time a reference is changed, copied or goes out of scope, incurring a constant overhead. When the count drops to zero the object can be immediately destroyed. The system needs a mechanism to (manually) handle cycles. You can find some horror stories by searching for the COM IUnknown interface.