2

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.

Robert S.
  • 25,266
  • 14
  • 84
  • 116
Larry Watanabe
  • 10,126
  • 9
  • 43
  • 46

6 Answers6

4

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
  • 155,851
  • 29
  • 291
  • 343
3

NO!

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

John Saunders
  • 160,644
  • 26
  • 247
  • 397
  • 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 Sep 15 '09 at 13:21
2

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
  • 687,336
  • 108
  • 737
  • 1,005
  • You are correct for local variables. The original question *looks* like it's a local variable. – MarkJ Jul 21 '09 at 18:01
1

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
  • 5,190
  • 6
  • 30
  • 42
  • 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 Jul 20 '09 at 20:54
  • 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 Jul 21 '09 at 14:19
1

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
  • 1,689
  • 5
  • 16
  • 29
0

It's important to understand in .net (or Java) that a variable, field, or other storage location of class type Foo doesn't hold a Foo. It holds a reference to a Foo. Likewise, a List<Foo> doesn't hold Foos; it holds references to Foos. In many cases, a variable will be known by the programmer to hold the only extant reference to some particular Foo. Unfortunately, the compiler has no general means of knowing whether a storage location holds the only extant reference to an object, or whether it holds one of many.

The main rule about IDisposable is that objects which implements IDisposable should be told they are no longer need sometime between the moment they are in fact no longer needed, and the time that all references to them are abandoned. If an object hasn't been Disposed, and code is about to overwrite the only extant reference to it (either by storing null, or by storing a reference to something else), the object should have its Dispose method called. If there exist other reference to the object, and the holders of those references expect to keep using it, Dispose should not be called. Since the compiler can't tell which situation applies, it doesn't call Dispose but leaves that to the programmer (who hopefully has a better idea of whether or not to call it).

supercat
  • 77,689
  • 9
  • 166
  • 211