TSS had a bit linked to Artima today, reading:
Given that a programmer in Java or C# should be setting their pointers to NULL, what is the difference between that and explcitly calling a delete? The answer is more or less nothing. The real question is what happens when the programmer makes the inevitable mistake. Undefined behaviour is unacceptable for most of us sane people, but silently keeping things alive is a very hard to detect resource leak. I think a programmer would have the best of both worlds if their language avoided undefined behaviour, threw errors when things aren't deleted when they should, and prevented things from being deleted which shouldn't be.
Now, I pretty much immediately wanted to call bullshit on that. Really, in terms of just letting a variable fall out of scope, who really cares.
Cedric says, however:
Setting pointers to null does help the garbage collector. Regardless of the type of garbage collector you are using (generational, mark and sweep, etc...), setting a pointer to null allows the algorithm to skip a step in its implementation. If you don't set the pointer to null, the virtual machine will try to follow this pointer and will, later, realize that the pointed object only has one reference, and is therefore up for garbage collection. If you set the pointer to null, you save one step. It's as simple as that.
Now, while this practice helps the garbage collector, it doesn't help it by much, and I would argue that for most applications (JSE and JEE), you should never bother using it. It's a bit different for JME, though, where every byte counts and where I recommend (and personally use) this technique with lazy initialization to limit the amount of heap used by my applications.
Finally, one last comment:
Setting references to NULL to "help" GC is the easiest way to sign up for a NPE in other parts of the code.
This strikes me as a code smell. If you are keeping a pointer alive just in case some other part of your code uses it, you have a bigger problem than memory management. Regardless of your implementation, you should always be able to answer the question: "Is this object still needed after this point or not?". Sometimes, the answer is "maybe" (multithreaded code for example), but in most cases, the answer to this question should be a clear "yes" or "no".
I would say if you are creating so many extra pointers that you have to worry about it, you might have a problem anyway. But really...
Sorry, while I think understanding when you are about to do something galactically stupid is important, worrying about how stuff is garbage collected is the least of problems in the world. Especially when I see people dumping temp stuff into a static HashMap and never emptying anything out of it until the memory just spirals out of control.
Comments
RE: To Null or Not To Null
Granted I'm no Java guru, but isn't that just plain wrong? Calling delete on a pointer would free the object and invalidate all references to it. Setting one of the references to NULL definately would not have the same behavior unless it was the only reference. Am I missing the point?
Speaking of, I've been using shared_ptr from the boost library, which is slated to be part of the STL come C++0x. It's a really nice implementation of a reference-counting smart pointer. As the shared_ptr object gets copied around on the stack, automaic copy constructor/destructor invocation change a static reference counter, and the shared_ptr's memory gets freed when the count goes to 0. Lots of nice C++ stuff is coming from boost.org.
RE: To Null or Not To Null
It depends on how you are doing it. Somethings are more important than others. Yes, you would have to null out all references to an object, but take for instance:
Iterator it = //some iterator; FooClass foo; //note, this is still unallocated since it was never initialized even to null while( it.hasNext() ){ //if it is empty, foo is never allocated. foo = (Foo) it.next(); foo.doSomething(); foo = null; //foo reference is released since we // don't need it anymore. Calling this // will automatically kick the GC // counter down to 0 since it doesn't // have to scope check. }This is generally better than reallocating a pointer for each FooClass by declaring foo inside the block. However, even so, once foo (if declared inside the block) falls out of scope, the garbage collector should see it, it just requires one more check.
The real issue with this in my mind, however, goes to the nature of J2EE work: since almost everything is server-request based, it is actually BAD to try and get the GC to run while your process is running, since the downtime between requests or a flurry of them is a better place to do that than to degrade responsiveness of an individual request. To Cedric's point, if you are worried more about heap size than speed, then yes, it would be better to null it out.
RE: To Null or Not To Null
Ohh you're talking about garbage collecting the references, not the actual objects. Now I follow. And really I guess I'm with ya in that I don't see the pressing need; if you're running into heap size problems due to 4 byte pointers, then maybe you have bigger problems.
RE: To Null or Not To Null
Yeah, this is a failure of terminology, really. When people say "pointer" in Java or C# what they really mean is "reference". There is no such thing as an actual "pointer" in J/C#.