To set to Nothing (null) or not…


At lunch today at TechEd I had a chance to talk to some folks from a Fortune 500 company.  It seems their IT shop is having a debate internally whether they should “null out” all their references when they are done with it.  We had almost the exact some question comes up at a customer meeting right before hand… Two points are enough to create a trend line for me, so I thought I’d write a blog on the topic while I sit outside of Cabana 5 (come on by if you’d like). 


 


No, you don’t need to null out all your managed references.  The GC will free the memory and call the finalizers when the instance goes out of scope.  However, there really two things you should do.


1)       Get educated on some basics of how the GC works. Such as: Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework and Writing Faster Managed Code: Know What Things Cost”


2)       Use perf tools to find out where your real allocation issues are.  There maybe some large, long lived objects that should be nulled out when you are no longer using them. Check out CLRProfiler.


 


 


One pattern these folks mentioned was wrapping an entire function in a try..finally and null resources in the finally… such as:


 


    public static void Foo () {


       string s1;


       object foo;


       try {


          s1 = “foo”;


          foo = new Object();


        //do stuff


       } finally {


          s1 = null;


          foo = null;


       }


    }


 


Although try..finally is a good programming practice in general, in this case it is not needed and only adds complexity to your code. The instances will fall out of scope at the end of the method anyway so setting it to null gives no benefit. 

Comments (11)

  1. Eric Wilson says:

    In fact, isn’t nulling variables in the GC system only making things worse? I thought that I had read that the GC can determine if a variable is going to be used again in the method when a garbage collection starts. If the GC sees a variable being referenced farther down in the function, that means whatever the variable is pointing to now cannot be collected.

    This means that the object will be needlessly promoted to the next generation. Admittly this will only happen when the GC happens to kick off while the method is runnning but before the statements that null the variable are reached, so the effect would be minimal to say the least for almost all cases.

  2. SrinathV says:

    We had discussed this in our Perf & Scale guide,

    "Chapter 5 — Improving Managed Code Performance"

    http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/scalenetchapt05.asp

    Read section that says…for more details

    "Set Unneeded Member Variables to Null Before Making Long-Running Calls"

  3. Paul Wilson says:

    Excellent post. I’m in agreement that setting to null should be the exception, but I’ve also posted sample code that proved it can make a big difference at times and its been frustrating to see some people not want to acknowledge that — so great post — very well balanced.

  4. release builds of the above code will generate the following code

    L_0000: newobj instance void [mscorlib]System.Object::.ctor()

    L_0005: pop

    L_0006: ret

    which is equivallent to

    public static void Foo()

    {

    new object();

    }

    meaning set to null or not has the exact same result

  5. Mike Dimmick says:

    Could be derived from the old VB practice which Eric Lippert wrote about at http://weblogs.asp.net/ericlippert/archive/2004/04/28/122259.aspx.

    Basically setting to Nothing in the right order fixed some refcounting issues with the ADO classes in a particular version. That’s completely unnecessary under the CLR because it doesn’t do refcounting…

  6. Keith Patrick says:

    I don’t think I’ve ever set a variable to null for the purpose of encouraging garbage collection. I love the memory control in C++, and I love the lack of it (relatively speaking) in .Net, but the middle ground seems too nebulous for me in terms of when is best and when not. I just place my faith in the GC doing things in an intelligent way, and I try to structure my code around it, but not augment it such (counting on normal construct scopes to limit lifetime, for instance)

  7. To set to Nothing (null) or not……