views:

280

answers:

6

I recently saw some VB .NET code as follows:

Dim service = ...
Try
   ...
   service.Close()
Finally
   service = Nothing
End Try

Does assigning Nothing to service do anything? If it is a garbage collection issue, I am assuming that when "service" went out of scope the referenced object would be garbage collected and the dispose method called on the object.

It seems to me that assigning this variable Nothing can't really do anything, as there could be another reference to the object around so the reference counts haev to be checked anyways.

A: 

Looks like the answer lies in the response to this post: http://stackoverflow.com/questions/175454/loops-and-garbage-collection

ftank99
Thanks! It's what all my instincts and intuitions told me .. but never hurts to check :)
Larry Watanabe
@ftank: not quite; Object does not implement IDisposable, which adds another dimension.
Fredrik Mörk
This answer is not correct.
Robert S.
Er, no. Don't confuse object disposal with garbage collection.
Rob
Robert, can you explain why?
Larry Watanabe
@Larry: you can read some on garbage collection vs. Dispose here (C# samples, but the theory is the same for VB.NET): http://geekswithblogs.net/sdorman/archive/2007/07/21/using-garbage-collection-in-.net.aspx
Fredrik Mörk
Ok, now I understand you referring to the previous comment, not to the answer above. My confusion was about what you were "referring" (no pun intended) to.
Larry Watanabe
+3  A: 

NO!

You're seeing old VB6 code, where assigning Nothing reduced the reference count on COM objects.

John Saunders
Thanks! I'm actually looking at VB .NET code, but I think the person who advised me to do this had developed this habit from VB6 coding practices. This explains to me why one would even assign nothing to a variable - having used gc for many years and reference counting only briefly, the reference counting possibility didn't even occur to me.
Larry Watanabe
+4  A: 

It only releases the reference, which may mean that the object is available for garbage collection (there could still be other variables referencing the same object). If the object implements IDisposable, you need to call Dispose explicitly, otherwise you may have a resource leak.

Fredrik Mörk
Well, not a memory leak. Just a resource leak.
John Saunders
@John: so true; got sloppy with terms there. Corrected the post. Thanks :o)
Fredrik Mörk
+1  A: 

Assinging NULL to a reference in .NET does not help to clean the object away. It might help the garbage collector to run a little quicker in some corner cases but that's not important at all. It does not call dispose, either (when dealing with a disposable)

I love to assign NULL anyways to explicitly state that I won't use that other object anymore. So it has much more to do with catching bugs (you'll get a nullreference exception instead of possibly calling into some other object - which might fail or even silently create some side effects.)

So assigning NULL after closing another object (File or whatever) is a "code cleanliness" thing that eases debugging, it's not a help to the garbage collector (except in some really strange corner cases - but when you need to care about that you WILL know more about the garbage collector than you ever wanted to know anyways ...)

froh42
Limiting the scope of a variable is even better for avoiding bugs, as you can't even reach the variable. That way the compiler gives you the error immediately instead of getting it at runtime.
Guffa
Guffa, that's definitly correct. I use that technique exclusively for fields in a class. In C++/C# I strongly use tight scoping (and in C++ you can use the scope even for controlling the creation/destruction of objects, google RAII for more info - something where C#'s using/IDisposable is only a weak replacement for. )
froh42
+2  A: 

In most situations assigning null (Nothing) to a reference makes no difference to garbage collection what so ever.

The garbage collector doesn't care about scope, it only cares about usage. After the point in the code where the object is used the last time, the garbage collector knows that it can collect it because it won't be used any more.

Assigning null to the reference doesn't count as using the object, so the last point of usage is before that code. That means that when you clear the reference the garbage collector may already have collected the object.

(In debug mode though the usage of a variable is expanded to it's scope, so that the debugger can show the value of the variable throughout it's scope.)

Guffa
You are correct for local variables. The original question *looks* like it's a local variable.
MarkJ
+1  A: 

As everybody has already said, setting to nothing does not force garbage collection, if you want to force GC then you would be far better to use the using ke word

   Using objA As A = New A()
       objA.DoSomething()
   End Using

You still don't need to set to nothing as the End Using tells the Garbage collection that the object is no longer to be used

spacemonkeys