Nulling an object

Discussion in 'Java' started by Frank Cisco, May 17, 2009.

  1. Frank Cisco

    Frank Cisco Guest

    If you null and object ie. obj = null, when is it cleared from memory?
    Immediately or at the next garbage collection?
     
    Frank Cisco, May 17, 2009
    #1
    1. Advertising

  2. Frank Cisco

    Arne Vajhøj Guest

    Frank Cisco wrote:
    > If you null and object ie. obj = null, when is it cleared from memory?
    > Immediately or at the next garbage collection?


    You null a ref to an object. The object that the ref previously
    pointed to will be GC'ed after that assuming that there are no other
    refs to it.

    Note that there is very rarely any use for explicit nulling
    in Java. Having the ref not being ref'ed any more is sufficient.

    Arne
     
    Arne Vajhøj, May 17, 2009
    #2
    1. Advertising

  3. Frank Cisco wrote:
    > If you null and object ie. obj = null, when is it cleared from memory?
    > Immediately or at the next garbage collection?


    When the garbage collector decides to collect it. It really doesn't
    matter to you and setting it to null isn't really necessary and may not
    do anything for you anyway.


    --

    Knute Johnson
    email s/nospam/knute2009/

    --
    Posted via NewsDemon.com - Premium Uncensored Newsgroup Service
    ------->>>>>>http://www.NewsDemon.com<<<<<<------
    Unlimited Access, Anonymous Accounts, Uncensored Broadband Access
     
    Knute Johnson, May 17, 2009
    #3
  4. Frank Cisco

    Lew Guest

    Frank Cisco wrote:
    >> If you null and object ie. obj = null, when is it cleared from memory?
    >> Immediately or at the next garbage collection?


    Arne Vajhøj wrote:
    > You null a ref to an object. The object that the ref previously
    > pointed to will be GC'ed after that assuming that there are no other
    > refs to it.


    To amplify on what Arne said, you don't "null an object". That doesn't exist.

    After all references ("refs") to an object disappear, the object might be
    reclaimed by garbage collection (GC). Or it might not. Ever.

    > Note that there is very rarely any use for explicit nulling
    > in Java. Having the ref not being ref'ed any more is sufficient.


    There are occasional exceptions, as explained by Josh Bloch in /Effective
    Java/, Item 6 - essentially when you have logic that manages memory in a way
    additional to mere allocation, you have to dereference such extra management.
    Put more clearly, when you have hidden references to an object, such as in a
    collection like a Stack, those references keep an object alive even after the
    program is through with it. That's called "unintentional object retention",
    or "packratting". You might have to null out those hidden references, but
    other than in that specific situation you don't have to and shouldn't.

    --
    Lew
     
    Lew, May 17, 2009
    #4
  5. Frank Cisco

    Tom Anderson Guest

    On Sun, 17 May 2009, Arne Vajh?j wrote:

    > Frank Cisco wrote:
    >> If you null and object ie. obj = null, when is it cleared from memory?
    >> Immediately or at the next garbage collection?

    >
    > You null a ref to an object. The object that the ref previously
    > pointed to will be GC'ed after that assuming that there are no other
    > refs to it.
    >
    > Note that there is very rarely any use for explicit nulling in Java.
    > Having the ref not being ref'ed any more is sufficient.


    The only time it's important is where you have a reference from a
    long-lived structure to a large structure that you no longer need. The
    long-lived structure can be an object or a stack frame. If you're writing
    a class where the lifetime is unknown (a library class, say), and the size
    of the referent is large or unknown, i think it's prudent to null out the
    variable when you can. ArrayList nulls out slots in its array when
    elements are removed, for example; ISTR that an early version didn't, and
    that this led to hard-to-debug memory leaks.

    An example of the stack frame case was a program i worked on a little
    while ago which looked like:

    public void main(String[] args) {
    BigXMLDocument conf = loadConfigFile();
    Problem prob = initialiseProblem(conf);
    prob.solve();
    printResult(prob);
    }

    The XML tree for the config file wasn't needed after the creation of the
    problem object, but because the reference to it was still live, it
    couldn't be collected, and so sat around wasting memory while the
    long-running solve method ran. Explicitly setting the variable to null
    before going into solve would have avoided this.

    However, what we actually did was to simply do an extract method
    refactoring on the first two lines. That pushed the reference down into a
    stack frame which died before solve was called, and shaved tens of
    megabytes (woo!) off the heap usage. Where you can do this, it's more
    elegant than explicit nulling - putting short-lived things on the stack is
    generally a good idea.

    tom

    --
    King Kong. In Cannes. On a date with Spiderman.
     
    Tom Anderson, May 17, 2009
    #5
  6. Frank Cisco

    Lew Guest

    Tom Anderson wrote:
    > On Sun, 17 May 2009, Arne Vajh?j wrote:
    >
    >> Frank Cisco wrote:
    >>> If you null and object ie. obj = null, when is it cleared from
    >>> memory? Immediately or at the next garbage collection?

    >>
    >> You null a ref to an object. The object that the ref previously
    >> pointed to will be GC'ed after that assuming that there are no other
    >> refs to it.
    >>
    >> Note that there is very rarely any use for explicit nulling in Java.
    >> Having the ref not being ref'ed any more is sufficient.

    >
    > The only time it's important is where you have a reference from a
    > long-lived structure to a large structure that you no longer need. The
    > long-lived structure can be an object or a stack frame. If you're
    > writing a class where the lifetime is unknown (a library class, say),
    > and the size of the referent is large or unknown, i think it's prudent
    > to null out the variable when you can. ArrayList nulls out slots in its
    > array when elements are removed, for example; ISTR that an early version
    > didn't, and that this led to hard-to-debug memory leaks.
    >
    > An example of the stack frame case was a program i worked on a little
    > while ago which looked like:
    >
    > public void main(String[] args) {
    > BigXMLDocument conf = loadConfigFile();
    > Problem prob = initialiseProblem(conf);
    > prob.solve();
    > printResult(prob);
    > }
    >
    > The XML tree for the config file wasn't needed after the creation of the
    > problem object, but because the reference to it was still live, it
    > couldn't be collected, and so sat around wasting memory while the
    > long-running solve method ran. Explicitly setting the variable to null
    > before going into solve would have avoided this.


    So would have
    Problem prob = initialiseProblem( loadConfigFile() );

    Uglier, but also effective:

    Problem prob;
    {
    BigXMLDocument conf = loadConfigFile();
    prob = initialiseProblem(conf);
    }
    prob.solve();

    etc.

    > However, what we actually did was to simply do an extract method
    > refactoring on the first two lines. That pushed the reference down into
    > a stack frame which died before solve was called, and shaved tens of
    > megabytes (woo!) off the heap usage. Where you can do this, it's more
    > elegant than explicit nulling - putting short-lived things on the stack
    > is generally a good idea.


    This is much better than explicit nulling.

    --
    Lew
     
    Lew, May 17, 2009
    #6
  7. Lew wrote:
    >
    >> However, what we actually did was to simply do an extract method
    >> refactoring on the first two lines. That pushed the reference down
    >> into a stack frame which died before solve was called, and shaved
    >> tens of megabytes (woo!) off the heap usage. Where you can do this,
    >> it's more elegant than explicit nulling - putting short-lived
    >> things
    >> on the stack is generally a good idea.

    >
    > This is much better than explicit nulling.


    Why? I'd think

    document = null; // Allow the document to be collected

    makes the intent clearer than

    doInit();

    giving the reader no clue why that part of the initialization logic
    was put into a seperate method.
     
    Mike Schilling, May 17, 2009
    #7
  8. Frank Cisco

    Lew Guest

    Tom Anderson wrote:
    >>> However, what we actually did was to simply do an extract method
    >>> refactoring on the first two lines. That pushed the reference down
    >>> into a stack frame which died before solve was called, and shaved
    >>> tens of megabytes (woo!) off the heap usage. Where you can do this,
    >>> it's more elegant than explicit nulling - putting short-lived
    >>> things
    >>> on the stack is generally a good idea.


    Lew wrote:
    >> This is much better than explicit nulling.


    Mike Schilling wrote:
    > Why? I'd think
    >
    > document = null; // Allow the document to be collected
    >
    > makes the intent clearer than
    >
    > doInit();
    >
    > giving the reader no clue why that part of the initialization logic
    > was put into a seperate method.


    What intent? To uselessly help the GC?

    The closing brace gives ample clarity to the intent that a variable go out of
    scope.

    Explicit nulling implies that such a thing is necessary to the logic of the
    program, a false implication in most cases. Putting almost any explicit logic
    in to "help" GC is a red herring, not germane to the business logic of the
    code. Ergo, documenting such non-germane code is only compounding the error.

    Authors like Brian Goetz refer to explicit nulling as a mistake:
    <http://www.ibm.com/developerworks/library/j-jtp01274.html>
    > Sun warned of this risk [reference retention] and explained how explicit
    > nulling was needed in cases like the pop() example above. Unfortunately,
    > programmers often take this advice too far, using explicit nulling in the
    > hope of helping the garbage collector. But in most cases, it doesn't help
    > the garbage collector at all, and in some cases, it can actually hurt your
    > program's performance.

    ....
    > Explicit nulling should be saved for cases where your program is subverting
    > normal scoping rules for performance reasons, such as the stack example in
    > Listing 3


    --
    Lew
     
    Lew, May 17, 2009
    #8
  9. Frank Cisco

    Lew Guest

    Peter Duniho wrote:
    > In fact, even the example Lew gives of a Stack is in reality unlikely to
    > require specific handling. In particular, if you're actually _done_


    Joshua Bloch and Brian Goetz and Sun generally disagree with you. If the
    Stack lives a long time, items being popped from it might need to have the
    popped element in the Stack nulled out, or else the stack itself keeps the
    object reachable, depending on the implementation.
    <http://www.ibm.com/developerworks/library/j-jtp01274.html>,
    which references
    <http://java.sun.com/developer/TechTips/1997/tt0903.html#tip2>
    Item 6 of /Effective Java/ makes substantially the same point, with a more
    thorough explanation.
    <http://books.google.com/books?id=ka2VUBqHiWkC&pg=PA24>

    > with the Stack, simply getting rid of the reference to the Stack itself
    > is sufficient for releasing all the objects that the Stack itself
    > references. Once the Stack becomes unreachable, so too do all the
    > objects the Stack references (assuming they aren't referenced elsewhere,
    > of course). It's only if you intend to retain the Stack, but no longer
    > want the objects to which it refers do you need to do any clearing of
    > references (and of course, the most direct way to do that is simply to
    > call the clear() method).
    >
    > (Of course, in the real world a Stack is usually not discarded until
    > empty, at which point it doesn't have references to other objects
    > anyway, but that's not really germane to the point here :) ).


    It is germane in the reverse, wherein the Stack is not yet discarded but you
    wish references above the current top of stack to be.

    The key is that constructs like Stack and Map take over part of the memory
    management burden and hold on to references in ways that the programmer might
    forget. This "packratting", long-lived structures holding on to
    now-irrelevant references, is the source of so-called "memory leaks" in Java.

    Goetz, in the above-referenced DeveloperWorks article, cautions against taking
    this principle too far.

    Another solution to packratting involves WeakReferences.

    --
    Lew
     
    Lew, May 17, 2009
    #9
  10. Lew wrote:
    > Tom Anderson wrote:
    >>>> However, what we actually did was to simply do an extract method
    >>>> refactoring on the first two lines. That pushed the reference
    >>>> down
    >>>> into a stack frame which died before solve was called, and shaved
    >>>> tens of megabytes (woo!) off the heap usage. Where you can do
    >>>> this,
    >>>> it's more elegant than explicit nulling - putting short-lived
    >>>> things
    >>>> on the stack is generally a good idea.

    >
    > Lew wrote:
    >>> This is much better than explicit nulling.

    >
    > Mike Schilling wrote:
    >> Why? I'd think
    >>
    >> document = null; // Allow the document to be collected
    >>
    >> makes the intent clearer than
    >>
    >> doInit();
    >>
    >> giving the reader no clue why that part of the initialization logic
    >> was put into a seperate method.

    >
    > What intent? To uselessly help the GC?



    >
    > The closing brace gives ample clarity to the intent that a variable
    > go out of scope.
    >


    We were specifically discussing the case where it is necessary,
    because the variable won't go out of scope anytime soon. This can
    also occur with nested scopes within a method, since variables within
    them don't go "out of scope" for GC purposes until the method returns.


    > Explicit nulling implies that such a thing is necessary to the logic
    > of the program, a false implication in most cases. Putting almost
    > any explicit logic in to "help" GC is a red herring, not germane to
    > the business logic of the code. Ergo, documenting such non-germane
    > code is only compounding the error.


    The most important code to comment is that put in for an important but
    non-obvious reason .
     
    Mike Schilling, May 17, 2009
    #10
  11. Peter Duniho wrote:
    >
    > In fact, even the example Lew gives of a Stack is in reality
    > unlikely
    > to require specific handling. In particular, if you're actually
    > _done_ with the Stack, simply getting rid of the reference to the
    > Stack itself is sufficient for releasing all the objects that the
    > Stack itself references.


    The issue witrh stacks (and ArrayLists) is that a naive implementation
    retains unnecessary references to objects. Assume something like:
    (not tested or compiled, so please ignore any typos, as well as the
    fact that neither overflow nor underflow is handled.)

    public class SimpleStack
    {
    private Object stack[] = new Object[MAX_SIZE];
    int size = 0;

    public void push(Object o)
    {
    stack[++size] = o;
    }

    public Object pop()
    {
    return stack[--size];
    }
    }

    If you push three objects and then pop two of them, the stack still
    references all three, and will continue to do so for an indefinite
    period of time. The solution is to replace pop() with

    public Object pop()
    {
    Object o = stack[--size];
    stack[size] = null; // remove reference to o.
    return o;
    }

    Having popped an object, the stack should forget about it completely.
     
    Mike Schilling, May 17, 2009
    #11
  12. Frank Cisco

    Lew Guest

    Lew wrote:
    >> The closing brace gives ample clarity to the intent that a variable
    >> go out of scope.


    Mike Schilling wrote:
    > We were specifically discussing the case where it is necessary,
    > because the variable won't go out of scope anytime soon. This can


    That sounds like it would be better fixed by properly scoping the variable
    than by a null-assignment hack. In the specific discussion to which you
    refer, that was the answer in fact; Tom Anderson discussed how his project
    solved it by a far better means than the null-assignment hack.

    > also occur with nested scopes within a method, since variables within
    > them don't go "out of scope" for GC purposes until the method returns.


    In all JVM implementations? In the presence of Hotspot? Forever more?

    Normally the source should not make assumptions specific to a particular
    version of the JVM. In the case of a putative optimization, there should be
    measurement and evidence first, re-evaluation of the algorithm second, and
    micro-optimization third. Tom Anderson's anecdote was a good example; it
    showed how changing the algorithm solved the measured performance problem
    without resorting to implementation-specific hacks.

    In light of the experts' advice that indiscriminate use of null assignment is
    superfluous and occasionally harmful, I'd look for a very strong reason to do
    otherwise.

    --
    Lew
     
    Lew, May 17, 2009
    #12
  13. Frank Cisco

    Lew Guest

    Peter Duniho wrote:
    > Whether those you named disagree with me depends on what they consider a
    > bug-free implementation of a stack.


    They consider a bug-free implementation to be that which follows their advice.
    It is the implementation that requires "specific handling", as I've been
    saying right along.

    > I would say that a stack implementation that retains a reference to an
    > object popped or otherwise cleared from the stack is not bug-free.


    But then we agree here. I am discussing the implementation of the stack, not
    its use. That was clear from the examples I linked, which discuss stack
    implementation, not use.

    > But yes, if you're dealing with a buggy stack implementation, you might
    > have to go to extra work to ensure your popped object really is no


    I refer to the work done by the stack implementation itself, not by the
    clients of the stack, as do the examples that I cited.

    > longer referenced by the stack. What that "extra work" might be would
    > depend on the implementation, but in the most obvious case would involve
    > pushing and then immediately popping a null reference.


    No, that is from the perspective of the stack client. The stack
    implementation has to null the outdated reference as part of the 'pop()'
    implementation. See the examples that I cited.

    > My comments are all intended to be in the context of assuming a bug-free
    > implementation. YMMV.


    And my comments are all intended to be in the context of one writing that
    implementation to ensure that clients may safely make that assumption.

    --
    Lew
     
    Lew, May 18, 2009
    #13
  14. Lew wrote:
    > Lew wrote:
    >>> The closing brace gives ample clarity to the intent that a
    >>> variable
    >>> go out of scope.

    >
    > Mike Schilling wrote:
    >> We were specifically discussing the case where it is necessary,
    >> because the variable won't go out of scope anytime soon. This can

    >
    > That sounds like it would be better fixed by properly scoping the
    > variable than by a null-assignment hack. In the specific discussion
    > to which you refer, that was the answer in fact; Tom Anderson
    > discussed how his project solved it by a far better means than the
    > null-assignment hack.
    >> also occur with nested scopes within a method, since variables
    >> within
    >> them don't go "out of scope" for GC purposes until the method
    >> returns.

    >
    > In all JVM implementations? In the presence of Hotspot? Forever
    > more?


    That's how it's been documented.

    >
    > Normally the source should not make assumptions specific to a
    > particular version of the JVM.


    Though it's only sensible to put in workarounds for issues with JVMs
    that the code is going to be run on, provided that they're
    well-documented. Code runs on real JVMs, not hypotherical perfect
    ones.

    > In the case of a putative
    > optimization, there should be measurement and evidence first,
    > re-evaluation of the algorithm second, and micro-optimization third.
    > Tom Anderson's anecdote was a good example; it showed how changing
    > the algorithm solved the measured performance problem without
    > resorting to implementation-specific hacks.


    Not at all. It was an example of another way to solve the problem
    that Tom felt was more "elegant". I disagree, and don't see why my
    criteria of making the problem and its solution clear in the code are
    of less value than Tom's (and apparently your) esthetic feelings.
     
    Mike Schilling, May 18, 2009
    #14
  15. Frank Cisco

    Tom Anderson Guest

    On Sun, 17 May 2009, Mike Schilling wrote:

    > Lew wrote:
    >
    >>> However, what we actually did was to simply do an extract method
    >>> refactoring on the first two lines. That pushed the reference down
    >>> into a stack frame which died before solve was called, and shaved tens
    >>> of megabytes (woo!) off the heap usage. Where you can do this, it's
    >>> more elegant than explicit nulling - putting short-lived things on the
    >>> stack is generally a good idea.

    >>
    >> This is much better than explicit nulling.

    >
    > Why? I'd think
    >
    > document = null; // Allow the document to be collected
    >
    > makes the intent clearer than
    >
    > doInit();
    >
    > giving the reader no clue why that part of the initialization logic
    > was put into a seperate method.


    The initialisation code that was pulled out was all the stuff to do with
    parsing XML. That seems like a pretty natural unit of separation to me,
    and not something needing comment - the reduced memory footprint was a
    nice side-effect of cleaner organisation, even if the motivations weren't
    that way round. If the stuff pulled out was less of a natural unit,
    perhaps you'd be right.

    tom

    --
    They didn't have any answers - they just wanted weed and entitlement.
     
    Tom Anderson, May 18, 2009
    #15
  16. Frank Cisco

    Lew Guest

    Peter Duniho wrote:
    > On Sun, 17 May 2009 16:42:53 -0700, Lew <> wrote:
    >
    >> [...]
    >>> My comments are all intended to be in the context of assuming a
    >>> bug-free implementation. YMMV.

    >>
    >> And my comments are all intended to be in the context of one writing
    >> that implementation to ensure that clients may safely make that
    >> assumption.

    >
    > You should have made that clear from the outset then. Your statement
    > was: "when you have hidden references to an object, such as in a
    > collection like a Stack, those references keep an object alive even
    > after the program is through with it".
    >
    > You wrote "a collection like a Stack", not "an implementation of a
    > stack". The built-in Stack class surely does not have that particular bug.


    Christ, Peter, I said *in* the collection and *like* a Stack, and I pointed to
    two examples that discussed the implementation, not the use. Sheesh.

    I was making it clear.

    --
    Lew
     
    Lew, May 18, 2009
    #16
  17. Frank Cisco

    Frank Cisco Guest

    "Frank Cisco" <> wrote in message
    news:AKYPl.30116$2...
    > If you null and object ie. obj = null, when is it cleared from memory?
    > Immediately or at the next garbage collection?


    Cheers for the responses. I guess the only way to say whether this is an
    effective practice is to see how the GC does it's work - maybe helping the
    GC out isn't such a bad idea. I've noticed a lot of null setting in the core
    java APIs - so it can't be that harmful. Anyone from Sun Microsystems about?
     
    Frank Cisco, May 18, 2009
    #17
  18. Frank Cisco

    Lew Guest

    Peter Duniho wrote:
    > And frankly, I could have tolerated the comments, except that
    > you insisted on making it about how what I had written was _wrong_,


    That's not what I made it about, and certainly nothing I was insisting on. It
    just seemed that way because we were in utterly different contexts. It was
    about whether structures like Stack were unlikely to require special handling
    - it was an attempt to get at the truth. To that end I cited experts, indeed
    the very ones who wrote relevant parts of the Java API that dealt with this
    issue, who spoke of when one needs to null out references and when one doesn't.

    I've reviewed my posts in this thread, and they make no special effort to
    claim that what you wrote was wrong. They just continually cited examples of
    how to implement stacks and such without packratting. When I found that I was
    not making my context clear, I clarified it and pointed out that we agree.
    How would I be making what you wrote wrong and also claiming to agree with it?

    > when in fact nothing I wrote was wrong.


    What you wrote about nulling out references was not wrong.

    --
    Lew
     
    Lew, May 18, 2009
    #18
  19. Peter Duniho wrote:
    > The reason that one does not normally need to be concerned is that what's
    > important is whether the object is reachable, not whether references to it
    > exist. You can have a very complicated data structure, but which is
    > referenced at the root by a single object reference. Once you're done
    > with that data structure, there's no need to traverse it, nulling out
    > references. As long as the root reference is discarded (which may in fact
    > involve nulling out a single reference), the rest of the data structure is
    > no longer reachable, and thus is automatically eligible for garbage
    > collection with no special effort from the program.


    In fact, traversal to null out may have the following drawbacks:
    0. It is unnecessary work for the CPU, and causes unnecessary
    cache and/or memory writes.
    1. It may reference memory pages that have been flushed out of the
    cache or even swapped out to disk, causing expensive refresh or
    swap operations.
    2. It may actually interfere with some types of garbage collectors
    that keep track which memory areas have been recently updated
    or traversed into.

    --

    "I'm a doctor, not a mechanic." Dr Leonard McCoy <>
    "I'm a mechanic, not a doctor." Volker Borchert <>
     
    Volker Borchert, May 18, 2009
    #19
  20. Frank Cisco

    Karl Uppiano Guest

    "Frank Cisco" <> wrote in message
    news:AKYPl.30116$2...
    > If you null and object ie. obj = null, when is it cleared from memory?
    > Immediately or at the next garbage collection?


    I have been programming in Java since ca. 1995, and I have never once
    bothered myself with "helping" GC. It is my considered opinion that GC is
    supposed to be automatic. If I wanted to worry about memory management, I
    would program in C++. Actually, I sometimes do, but I digress.

    In 15 years, I have had two sources of "memory leaks" in Java, both due to
    programmer error: Threads not actually terminating, and thus keeping
    references to all sorts of resources attached to them, and collections that
    still contained items that should have been removed. I've never encountered
    a need to explicitly null out any references. I suppose there are certain
    corner cases that would require it:

    - The stack example (although failure of a stack to truly unreference a
    popped element would be unexpected and, I hope, clearly documented)
    - Objects created near the head of the call stack (say, main) that remain in
    scope for a very long time, even though they are no longer needed. I suspect
    that there are ways of organizing the code so as to eliminate that behavior,
    but perhaps just setting the reference to null when finished with it is the
    simplest thing.
     
    Karl Uppiano, May 18, 2009
    #20
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Parthiv Joshi
    Replies:
    2
    Views:
    702
    Kalyan
    Jul 2, 2004
  2. Suresh Kojhani
    Replies:
    1
    Views:
    2,397
    Anushi
    Jul 29, 2004
  3. Chris Fink
    Replies:
    2
    Views:
    4,109
    David Waz...
    Jul 3, 2003
  4. jon wayne
    Replies:
    9
    Views:
    721
    Jim Langston
    Sep 22, 2005
  5. tshad

    ObjectDataSource nulling GridView

    tshad, Feb 4, 2010, in forum: ASP .Net
    Replies:
    3
    Views:
    752
    tshad
    Feb 5, 2010
Loading...

Share This Page