J
Jon Skeet [C# MVP]
In .NET, you are likely to adversely affect the performance of your
application by explicitly dereferencing your object (x = Nothing)! The GC
is optimized to look at running methods when collecting and to determine if
objects that still have application roots are actually going to be used in
the remainder of the method running. If you were to be cleaining up your
objects by setting them to Nothing, but hadn't reached that point of the
code yet, the GC would actually NOT mark your object that isn't going to be
used for any meaningful purpose for collection, now that you've got another
reference to it (the clean up code) later in the code.
I believe that was true at some point, and I guess it *might* still be
true for VB.NET, but it's not true for the C# 3.0 compiler and .NET
3.5. The compiler or JIT/GC - not sure which - understands that if the
only operation you're going to do on a variable is to write to it, it
doesn't count as a root.
Here's an example - compile with optimisation and without debug. (It
may work in other configurations, but that's what I've tried.)
using System;
using System.Threading;
public class GcTest
{
~GcTest()
{
Console.WriteLine("Finalized");
}
static void Main()
{
GcTest test = new GcTest();
Console.WriteLine("Before GC.Collect");
GC.Collect();
GC.WaitForPendingFinalizers();
// Make it clear this isn't a race condition for the console
Thread.Sleep(5000);
Console.WriteLine("Before test = null");
test = null;
Console.WriteLine("After test = null");
}
}
Output:
Before GC.Collect
Finalized
Before test = null
After test = null
I *totally* agree that it's a bad thing to do in terms of clarity, but
it doesn't have the performance effect you described.