Does setting Java objects to null do anything anymore?

62,747

Solution 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.

Solution 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.

Solution 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.

Solution 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.

Solution 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.

Share:
62,747

Related videos on Youtube

sal
Author by

sal

cat herder, technologist, software developer

Updated on July 08, 2022

Comments

  • sal
    sal almost 2 years

    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?

    • Jason Coco
      Jason Coco almost 15 years
      Profile it. On modern runtimes you shouldn't see any meaningful increase in performance or memory footprint.
    • sal
      sal almost 15 years
      @Jason, Profile it? That assumes I will profile a large enough set of cases to get an good enough result set to answer this. And that I don't pick a set of cases that VM is optimized enough to mask the gc and performance issues. That's why I'm asking this here. To get a sense of the cases where this is an issue.
    • palantus
      palantus almost 15 years
  • Pablo Santa Cruz
    Pablo Santa Cruz almost 15 years
    Is this a language issue or a VM implementation issue?
  • C. K. Young
    C. K. Young almost 15 years
    It's a "semantic" issue. Basically, because you've preallocated an array, the VM sees that. It knows nothing about the "logical" size of your container. Say you have an ArrayList of size 10, backed by a 16-element array. The VM can't know that items 10..15 aren't actually used; if those slots have contents, they will not be freed.
  • sal
    sal almost 15 years
    what about outside of container classes? In object composition where the inner object isn't de-allocated by the outer object is.
  • ubermensch
    ubermensch almost 15 years
    @sal The general rule of thumb is that if you can't reference it, it gets garbage collected. So if the outer object contains a reference to another object, assuming that the inner object does not have any other references, setting the outer object's one and only reference to null will cause the entire object to be garbage collected, including its orphaned references.
  • James Drinkard
    James Drinkard over 11 years
    If you are referring to a strong reference, yes this is true, but not for all references. Weak references in java can be garbage collected.
  • Brian White
    Brian White about 9 years
    Local variables can be optimized by the machine. Class variables cannot. I've seen worker threads (on a thread pool) not release their state objects after handling the request and thus pinning those objects in memory until the worker thread was given a new task (which promptly overwrote the old state objects with new ones). With big state objects and hundreds of worker threads (think: big http server), this can be massive amounts of memory held and copied around yet will never be used again.
  • Neil Coffey
    Neil Coffey about 9 years
    I should probably just add: the advice I give above is the advice to follow generally, assuming well-behaved libraries, a well-behaved VM etc. If you find that you have, say, a thread pool library that hangs on to objects after a job has finished, well... that's a bug in said thread pool library that could perhaps be worked around by nulling an object reference, but equally might be worked around by using a less buggy thread pool library. I'm not sure that such a bug changes general design principles.
  • Ruchir Baronia
    Ruchir Baronia over 8 years
    How do I remove a drawable from memory then?
  • Ruchir Baronia
    Ruchir Baronia over 8 years
    Just set it to null?
  • ACV
    ACV over 6 years
    In the same Item 6 you mentioned: Nulling out object references should be the exception rather than the norm.