Much credit to Sjoerd Verweij
Setting Objects to Nothing
Set X = Nothing does not destroy the object, it destroys the reference to it. This holds true for VB6 and VB.NET. Understanding the difference in how Garbage collection works in VB6 and VB.NET is a good thing to know.
VB6
In VB6 it's a variable going out of scope does the same thing. There is a reference counter for the variable, which gets set to 1 when the object is created, and incremented every time something starts pointing to it. Conversely, whenever something stops pointing to it, or that something gets destroyed (for example, when exiting the Sub the variable was declared in), the value is decremented. If it hits 0, the object is cleaned up. So, if all goes well:
Private Sub X
Dim Y As New Z ' 1
Dim A As Z
Set A = Y ' 2
Set A = Nothing ' 1
Set Y = Nothing ' 0
End Sub
It's inconsequential in this case, since:
Private Sub X
Dim Y As New Z ' 1
Dim A As Z
Set A = Y ' 2
Set A = Nothing ' 1
End Sub ' 0
Has the exact same effect. Sometimes, in VB6, you do want to do it, for example when you stop using something half-way through a procedure and want to free memory or resources:
Private Sub X
Dim Y As New Huge
...
Set Y = Nothing
For I = 1 To 50000
...
Next
End Sub
Now there is an interesting problem that can occur when something else starts pointing to it:
Dim A As Y
Private Sub X
Dim Z As New Y ' 1
Set A = Z '2
Set Z = Nothing ' 1
End Sub
Since A does not go out of scope and is therefore still alive, the instance of Y is still hanging around.T hat's fine as long as you realize this is happening. However, X might be 300 lines long, and it might be far from obvious that A is still pointing to the instance of Y when it exits. Reading the code, you might be deluded into thinking that the object is destroyed when it is not.
VB.NET
With garbage collection, the object does not have the counter "how many people are pointing to me".When an object is created, it's created. If a variable goes out of scope it does not affect the object itself.Whether or not you do Set X = Nothing, the object will not be destroyed. So how does it go away? At a certain time in the future (yes, that's vague), a garbage collection will be performed.At that time, the collector will look at the heap, and see an instance of a Y object.It then starts to look at all currently active variables outside of the heap (called roots) that point to it.If nothing points to it, Y is destroyed. GC only fires when the main heap has no free space and needs some to perform an operation.Finalize is called during GC and may never be called until your application quits.Also Note that GC will not clean up resources you set such as file pointers that you leave open.You must close these upon dispose. This means two things:
- Since you no longer know when an object is destroyed, you have to clean up manually if you want to be sure that Y closes the database connection it opened.But keep in mind that like outlined above, in VB6 it might not go away as planned either.You can destroy explicitly by implementing IDisposable.Dispose.
- This forever solves circular references. If you have X, Y and Z on the heap, which all point to each other, with the VB6 scheme it's hard to figure out to get all reference counts to 0 so everything will be cleaned up.The .NET garbage collector, however, can just see that nothing outside the heap is pointing to them and destroy them.