Does variable = null set it for garbage collection

19,484

Solution 1

That's old performance lore. It was true back in 1.0 days, but the compiler and the JVM have been improved to eliminate the need (if ever there was one). This excellent IBM article gets into the details if you're interested: Java theory and practice: Garbage collection and performance

Solution 2

From the article:

There is one case where the use of explicit nulling is not only helpful, but virtually required, and that is where a reference to an object is scoped more broadly than it is used or considered valid by the program's specification. This includes cases such as using a static or instance field to store a reference to a temporary buffer, rather than a local variable, or using an array to store references that may remain reachable by the runtime but not by the implied semantics of the program.

Translation: "explicitly null" persistent objects that are no longer needed. (If you want. "Virtually required" too strong a statement?)

Solution 3

The Java VM Spec

12.6.1 Implementing Finalization Every object can be characterized by two attributes: it may be reachable, finalizer-reachable, or unreachable, and it may also be unfinalized, finalizable, or finalized.

A reachable object is any object that can be accessed in any potential continuing computation from any live thread. Optimizing transformations of a program can be designed that reduce the number of objects that are reachable to be less than those which would naively be considered reachable. For example, a compiler or code generator may choose to set a variable or parameter that will no longer be used to null to cause the storage for such an object to be potentially reclaimable sooner.

Discussion

Another example of this occurs if the values in an object's fields are stored in registers. The program may then access the registers instead of the object, and never access the object again. This would imply that the object is garbage.

The object is reachable if it can be involved in any potential continuing computation. So if your code refers to a local variable, and nothing else refers to it, then you might cause the object to be collected by setting it to null. This would either give a null pointer exception, or change the behaviour of your program, or if it does neither you didn't need the variable in the first place.

If you are nulling out a field or an array element, then that can possibly make sense for some applications, and it will cause the memory to be reclaimed faster. Once case is creating a large array to replace an existing array referenced by a field in a class - if the field in nulled before the replacement is created, then it may relieve pressure on the memory.

Another interesting feature of Java is that scope doesn't appear in class files, so scope is not relevant to reachability; these two methods create the same bytecode, and hence the VM does not see the scope of the created object at all:

static void withBlock () {
    int x = 1;

    {
        Object a = new Object();
    }

    System.out.println(x+1);
}

static void withoutBlock () {
    int x = 1;

    Object a = new Object();

    System.out.println(x+1);
}

Solution 4

Not necessarily. An object becomes eligible for garbage collection when there are no live threads anymore that hold a reference to the object.

Local variables go out of scope when the method returns and it makes no sense at all to set local variables to null - the variables disappear anyway, and if there's nothing else that holds a reference the objects that the variables referred to, then those objects become eligible for garbage collection.

The key is not to look at just variables, but look at the objects that those variables refer to, and find out where those objects are referenced by your program.

Solution 5

It is useless on local variables, but it can be useful/needed to clear up instance variables that are not required anymore (e.g. post-initialization).

(Yeah yeah, I know how to apply the Builder pattern...)

Share:
19,484
ashurexm
Author by

ashurexm

Just a dude.

Updated on June 06, 2022

Comments

  • ashurexm
    ashurexm almost 2 years

    Help me settle a dispute with a coworker: Does setting a variable or collection to null in Java aid in garbage collection and reducing memory usage? If I have a long running program and each function may be iteratively called (potentially thousands of times): Does setting all the variables in it to null before returning a value to the parent function help reduce heap size/memory usage?

  • Pete Kirkham
    Pete Kirkham almost 14 years
    Only if the VM does not implement version 3 of the JVM spec.
  • Jesper
    Jesper almost 14 years
    It might be a good idea in certain special cases, but you should certainly not always set variables to null (note, it's important to be precise: you can't "set objects to null") out of habit, without thinking. That leads to a kind of superstitious programming, where you don't know why you are doing things, which is a bad idea.
  • Pete Kirkham
    Pete Kirkham almost 14 years
    Read the quote in my answer about reachability. If processHughList doesn't store a reference to the object referenced by hugeList, then it cannot 'be accessed in any potential continuing computation from any live thread' and so is unreachable, and hence eligible for garbage collection. If processHughList only uses the size and data array (assuming List is similar to an ArrayList) and these were JITted as register variables, then the object could even be collected before processHughList returns.
  • Ian Ringrose
    Ian Ringrose over 13 years
    It can be useful on local varibles, if the compiler can not work out it's self that the varible will not be read again. In most cases the compiler can work it out it's self.
  • Ian Ringrose
    Ian Ringrose over 13 years
    Only if the code is to complex for the compiler/jit to see that hugeList is not used after the call to processHugeList.
  • user207421
    user207421 about 8 years
    I doubt that it was ever true. I started at 1.1.2 and it wasn't true then. I think it was more a case of people getting used to garbage-collection for the first time in a mainstream language (?), and having C++ habits.
  • user207421
    user207421 about 8 years
    @IanRingrose The question is about nulling before procedure exit. The practice is useless. The compiler plays no part in garbage-collection.
  • user207421
    user207421 about 8 years
    The question is about nulling before return, and it is a waste of time.
  • istepaniuk
    istepaniuk almost 3 years
    you could include a reference to the article you are quoting
  • Pete
    Pete almost 3 years
    It was the article linked in the accepted answer, which now appears to be gone :(