John J. Hughes II said:
Ok, next time I find the time I'll do that...
By the way I don't believe that using and or setting a value to null
directly releases memory it just marks the memory as not being needed.
No, it does no such thing. Memory is never marked as not being needed -
the "mark" part of "mark and sweep" is marking things which *are* still
needed. Now, if the JIT can tell that a variable is no longer
reachable, it won't use that variable as a root when considering which
objects are still in use.
I have found that this is more relevant in nested instances when each
class or value tells the compiler the value is no longer needed. It
seems to help in loops where the new instance is used but does not
have as big an impact.
That suggests you believe you have some evidence that it has an effect.
I really doubt that you have - in release mode at least. (In debug mode
it would make a difference, but that's not a good reason to add more
code in, IMO.)
Here's some code which demonstrates that the GC doesn't need anything
to be set to null in order to finalize and then free it:
using System;
class Test
{
~Test()
{
Console.WriteLine ("Finalizer called");
}
static void Main()
{
Test t = new Test();
Console.WriteLine ("Calling GC");
GC.Collect();
GC.WaitForPendingFinalizers();
Console.WriteLine ("End of method");
}
}
The results are:
Calling GC
Finalizer called
End of method
So the finalizer is being called before the end of the method - no need
for nulling the variable out. Now, I know that the finalizer being
called isn't the same thing as the object being freed, but it shows
that the GC considers it not to be needed any more.
Personally I don't think it really clutters code for a couple of reasons.
First of all setting a value to null at the end of its logical use
reminds
me not to use it later, sort of note saying it not available. The
second
reason is I normally use them in the dispose call which is forced by the
using statement.
So you end up with something like:
public class myClass
{
byte[] data = byte[1000];
public void dispose()
{
data = null;
}
public void dosomething()
{
}
}
public void fun()
{
using(myClass c = new myClass)
c.dosomething();
}
If your class doesn't use any unmanaged resources either directly or
indirectly, there's really very little point in implementing
IDisposable in the first place. Just let the object get collected when
the GC notices it's not used - I don't think you're doing anything to
improve garbage collection using the above, but you're forcing yourself
to remember to use the using statement when you really don't need to.