Does setting Java objects to null do anything anym

2019-01-01 12:56发布

问题:

I was browsing some old books and found a copy of \"Practical Java\" by Peter Hagger. In the performance section, there is a recommendation to set object references to null when no longer needed.

In Java, does setting object references to null improve performance or garbage collection efficiency? If so, in what cases is this an issue? Container classes? Object composition? Anonymous inner classes?

I see this in code pretty often. Is this now obsolete programming advice or is it still useful?

回答1:

It depends a bit on when you were thinking of nulling the reference.

If you have an object chain A->B->C, then once A is not reachable, A, B and C will all be eligible for garbage collection (assuming nothing else is referring to either B or C). There\'s no need, and never has been any need, to explicitly set references A->B or B->C to null, for example.

Apart from that, most of the time the issue doesn\'t really arise, because in reality you\'re dealing with objects in collections. You should generally always be thinking of removing objects from lists, maps etc by calling the appropiate remove() method.

The case where there used to be some advice to set references to null was specifically in a long scope where a memory-intensive object ceased to be used partway through the scope. For example:

{
  BigObject obj = ...
  doSomethingWith(obj);
  obj = null;             <-- explicitly set to null
  doSomethingElse();
}

The rationale here was that because obj is still in scope, then without the explicit nulling of the reference, it does not become garbage collectable until after the doSomethingElse() method completes. And this is the advice that probably no longer holds on modern JVMs: it turns out that the JIT compiler can work out at what point a given local object reference is no longer used.



回答2:

No, it\'s not obsolete advice. Dangling references are still a problem, especially if you\'re, say, implementing an expandable array container (ArrayList or the like) using a pre-allocated array. Elements beyond the \"logical\" size of the list should be nulled out, or else they won\'t be freed.

See Effective Java 2nd ed, Item 6: Eliminate Obsolete Object References.



回答3:

Instance fields, array elements

If there is a reference to an object, it cannot be garbage collected. Especially if that object (and the whole graph behind it) is big, there is only one reference that is stopping garbage collection, and that reference is not really needed anymore, that is an unfortunate situation.

Pathological cases are the object that retains an unnessary instance to the whole XML DOM tree that was used to configure it, the MBean that was not unregistered, or the single reference to an object from an undeployed web application that prevents a whole classloader from being unloaded.

So unless you are sure that the object that holds the reference itself will be garbage collected anyway (or even then), you should null out everything that you no longer need.

Scoped variables:

If you are considering setting a local variable to null before the end of its scope , so that it can be reclaimed by the garbage collector and to mark it as \"unusable from now on\", you should consider putting it in a more limited scope instead.

{
  BigObject obj = ...
  doSomethingWith(obj);
  obj = null;          //   <-- explicitly set to null
  doSomethingElse();
}

becomes

{
  {  
     BigObject obj = ...
     doSomethingWith(obj);
  }    //         <-- obj goes out of scope
  doSomethingElse();
}

Long, flat scopes are generally bad for legibility of the code, too. Introducing private methods to break things up just for that purpose is not unheard of, too.



回答4:

In memory restrictive environments (e.g. cellphones) this can be useful. By setting null, the objetc don\'t need to wait the variable to get out of scope to be gc\'d.

For the everyday programming, however, this shouldn\'t be the rule, except in special cases like the one Chris Jester-Young cited.



回答5:

Firstly, It does not mean anything that you are setting a object to null. I explain it below:

List list1 = new ArrayList();
List list2 = list1;

In above code segment we are creating the object reference variable name list1 of ArrayList object that is stored in the memory. So list1 is referring that object and it nothing more than a variable. And in the second line of code we are copying the reference of list1 to list2. So now going back to your question if I do:

list1 = null;

that means list1 is no longer referring any object that is stored in the memory so list2 will also having nothing to refer. So if you check the size of list2:

list2.size(); //it gives you 0

So here the concept of garbage collector arrives which says «you nothing to worry about freeing the memory that is hold by the object, I will do that when I find that it will no longer used in program and JVM will manage me.»

I hope it clear the concept.



回答6:

One of the reasons to do so is to eliminate obsolete object references. You can read the text here.