Geeks With Blogs
David Douglass .NET on My Mind

I've noticed some confusion amongst VB6 programmers who've moved to .NET regarding garbage collection, so I'd like to explain the differences.

VB6 is built on top of COM.  In COM, each object has a hidden reference count inside it, a count of the number of in scope variables that point to the object.  When you new an object the reference count is set to 1.  If you then assign that variable to another, the reference count is incremented to 2.  As those references go away, either by variables going out of scope or having a different value assigned to them, the reference count is decremented.  When the reference count goes to 0, there is no way for the object to get used and it gets garbage collected at that time.

In .NET, objects do not have a reference count.  Instead, the .NET run time maintains a list of what points to what.  When an object instantiates another object, the .NET run time keeps track of the relationship.  If the object gets passed around, it remembers those relationships also.  Eventually, all the pointers to an object go away.  At that point, unlike VB6, nothing happens; there simply exists an unreferenced object in memory.  At some point, so much garbage (i. e., unreferenced objects) will build up in memory that the .NET run time will decide to track down unreferenced objects and garbage collect them (that's a simplification, but it will serve).

These differences affect how to program.  In VB6, it is common to set a variable to nothing to force the reference count to drop to 0 and cause garbage collection of that object.  This doesn't make sense in .NET.  Setting something to nothing in .NET, assuming there is only 1 reference, simply cause the object to become a candidate for garbage collection at some later, undefined time.  If you find you really need to force garbage collection in .NET there are 2 options:

      1. Refactor your program to keep scopes as narrow as possible
      2. Use the Dispose pattern

Where and how you declare objects affects how long they are in scope.  Shared variables are in scope for the life of the program, member variables for as long as the object exists, and local variables until a function is exited.  Always strive for the narrowest scope, this way object will naturally garbage collect at the best time.

There can be times when you need to release an object at a specific point in a program.  This is done using the Dispose pattern.  See Dispose, Finalization, and Resource Management for a complete discussion.  The Twitter version is that the Dispose pattern lets you tell an object "You're done; release your resources now".  This is not the same as garbage collection; garbage collection still happens later as described above.  If you need to implement Dispose, pay close attention to the details.  I ran into a nasty bug when this wasn't done correctly, which I discussed at Observations on .NET Object Disposal.

The 2 options are not mutually exclusive at all.  #1 should always be done, #2 should be done whenever necessary.

There is an option 3 which should be avoided, calling the Collect method on the GC class.  Performance will suffer by using GC.Collect.

There is an important difference between forcing garbage collection in VB6 by setting a variable to nothing and forcing clean up in .NET by calling Dispose.  In VB6, garbage collection happens only once there is no way for the object to be accessed.  In .NET, as far as the run time is concerned, Dispose is just another function like any other (compilers treat Dispose special, but not the run time).  You can call Dispose no matter how many references exist to an object.  Also, nothing stops you from using an object after it has been disposed.  Whether this "works" depends on the design of the class.  Nonetheless, using an object after it has been disposed is a violation of the pattern.  Future maintainers of the code may assume the pattern has been followed correctly and cause objects to be unusable once disposed.

Posted on Sunday, November 30, 2008 11:47 AM | Back to top

Comments on this post: Garbage Collection in VB6 and .NET

# re: Garbage Collection in VB6 and .NET
Requesting Gravatar...
we want to catagrised way and priority of destroing obeject
Left by susheel pagare on Jun 25, 2009 2:15 AM

Your comment:
 (will show your gravatar)

Copyright © David Douglass | Powered by: