Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / April 2008

Tip: Looking for answers? Try searching our database.

variable = null; Memory Cleanup

Thread view: 
Angry Moth Town - 16 Apr 2008 15:26 GMT
I have several developers who insist on using the following method,
claiming that it helps reduce memory use by eliminating resources
faster than the garbage collector.  Personally, I don't think this is
effective.  Is this a useful method, or should we simply be letting
the garbage collector do its job?

/**
* This method closes the ResultSetMetaData if it is open.
*/
public static void closeResultSetMetaData(ResultSetMetaData rs)
{
    try {
        rs = null;
    } catch (Exception exp) {
        exp.printStackTrace();
    }
}
Gordon Beaton - 16 Apr 2008 15:18 GMT
> I have several developers who insist on using the following method,
> claiming that it helps reduce memory use by eliminating resources
[quoted text clipped - 13 lines]
>     }
> }

The method is completely bogus.

No method can change the object reference still held by the caller,
and calling the method just to null the resulting local reference is
nonsensical. Also no exceptions can be thrown within the given try
block, so catching one here is pointless.

/gordon

--
Stefan Ram - 16 Apr 2008 15:43 GMT
>I have several developers who insist on using the following method,
>[...]rs = null;

 This only changes the parameter copy of the reference,
 so it can not have any observable effect, and it will
 never throw. Its author does not seem to know basic Java.
Eric Sosman - 16 Apr 2008 15:52 GMT
> I have several developers who insist on using the following method,
> claiming that it helps reduce memory use by eliminating resources
[quoted text clipped - 13 lines]
>     }
> }

    This method seems utterly pointless.  Are you sure you've
given a proper illustration of the technique you're asking about?

Signature

Eric.Sosman@sun.com

Angry Moth Town - 16 Apr 2008 16:01 GMT
> > I have several developers who insist on using the following method,
> > claiming that it helps reduce memory use by eliminating resources
[quoted text clipped - 19 lines]
> --
> Eric.Sos...@sun.com

Eric,

Yes, this is the exact method, copied and pasted, and the explanation
I got was that it "clears up memory faster, because the garbage
collector is too slow."

I'm basically going to tell 25 offshore developers that this is
pointless, but I'm not a Java expert, so I wanted to run it through
the newsgroup before I insisted we change it.

This isn't as bad as it gets.
Jan Thomä - 16 Apr 2008 16:06 GMT
> This isn't as bad as it gets.

I fear exactly this is going to happen. I wonder what other "optimizations"
of that kind you will find in the code....

Jan
Eric Sosman - 16 Apr 2008 18:14 GMT
>>> I have several developers who insist on using the following method,
>>> claiming that it helps reduce memory use by eliminating resources
[quoted text clipped - 22 lines]
> pointless, but I'm not a Java expert, so I wanted to run it through
> the newsgroup before I insisted we change it.

    All right, tell them it's pointless.  It's pointless
for more than one reason:

    - First, setting `rs = null' affects only the method's
own copy of the argument value, and does not affect any copies
the caller might have.  If the caller does

    ResultSetMetadata myRs = ...;
    closeResultSetMetaData(myRs);

then myRs is not changed at all.  The object myRs refers to
is still "live" and is not eligible for garbage collection;
the method has made no change whatever in its status.

    - Second, the try/catch block is pointless, because there
is nothing in `rs = null' that can throw an Exception.  The
writer of the try/catch was a seriously confused person.

    - Third, setting all the references to a particular object
to null does not avoid garbage collection, it just makes the
object eligible for collection.  If the JVM decides to run the
garbage collector it will do so, and the collector may reclaim
the garbage object's memory.  "Clearing up the memory faster"
is almost entirely bogus; all that might happen is that the
memory could be reclaimed sooner.  Sooner != faster.

    (The "almost" is because some garbage collectors must
work harder to reclaim long-lived objects than those that die
young.  Setting all the references to null -- or pointing them
at other objects, or letting the references themselves die --
makes the object garbage, and making it garbage sooner rather
than later might let it get collected on the next GC instead
of on the one after it.  Thus the effective lifetime might
be shortened and the collector might therefore work a little
less hard -- but this is an effect so small it would be hard
to measure.)

    A suggestion: If your compatriots are so convinced that
their method produces a performance improvement, challenge them
to measure the size of the improvement by actual experiment.
Run the code with the method as it stands and run it again with
the guts of the method commented out, and ask them how much
difference it made.  My bet: If the measurement is done with
great care, the commented-out version will run just a hair
faster than the "optimized" original.

Signature

Eric.Sosman@sun.com

Angry Moth Town - 16 Apr 2008 18:42 GMT
> >>> I have several developers who insist on using the following method,
> >>> claiming that it helps reduce memory use by eliminating resources
[quoted text clipped - 71 lines]
> --
> Eric.Sosman@sun.com

Eric,

Thank you so much for this reply.  This is exactly what I suspected,
and definitely what I wanted to hear.

I suspect this came about after someone discovered that connections
have to be closed to prevent memory leaks, and decided we needed to
'close' everything we can.  I'm assuming that even:
ResultSet rs = ...
rs = null;
is pointless, since the collector will know to clean up rs after it is
no longer used?

The application this is being developed for is Sun Identity Manager,
so I can't really measure the performance of the difference, but the
logic you present above should be enough to convince people that this
is wrong, and start making changes.

Thanks again Eric, this is a big help.  Now I just need to get people
to stop adding 'throws Exception' to the end of every method...
Eric Sosman - 16 Apr 2008 21:15 GMT
> [...]
> I suspect this came about after someone discovered that connections
[quoted text clipped - 4 lines]
> is pointless, since the collector will know to clean up rs after it is
> no longer used?

    As long as `rs' itself remains reachable, the object it
refers to is also reachable and cannot be collected.  Setting
`rs' to null (or making it refer to a different object) may
make the original object collectible, if there are no other
living references to that object.

    The technique your colleagues are so fond of seems like
a distorted recollection of a technique one used to see in
some Java texts.  The outline looks like

    void method() {
       BigThing thing = new BigThing();
       // ... use `thing' for a while
       // ... memory-hungry code not using `thing'
    }

The idea here is that the variable `thing' survives until
the method returns, so the BigThing it points to doesn't
become collectible until then.  Its actual lifetime runs
all the way to the end of the method, but its "useful
lifetime" ends after the first comment.  If a BigThing is
really really big and the second half of the method uses a
lot of memory and/or runs for a really long time, it might
be worth while to "kill" the reference early by inserting
`thing = null;' between the two comments.

    The worth (if any) of this trick rests on the large
size of the BigThing and the time/space greed of the second
half of the method.  If a BigThing is not huge, the trick
isn't worth while.  If the method's second half is not a
big consumer of memory and/or time, the trick is not worth
while.  It's only worth while if BigThing is large *and*
the second half of the method is greedy.  And if that's the
case, I'd start to wonder whether the two halves of the
method might be better off if refactored into two methods
that run sequentially.

> Now I just need to get people
> to stop adding 'throws Exception' to the end of every method...

    Blecch.  Sounds like you'll soon be ready to write a
maintenance manual for the Augean Stables ...

Signature

Eric.Sosman@sun.com

Mark Thornton - 16 Apr 2008 21:37 GMT
>     void method() {
>         BigThing thing = new BigThing();
[quoted text clipped - 11 lines]
> be worth while to "kill" the reference early by inserting
> `thing = null;' between the two comments.

Its real lifetime only extends to the point of last use which need not
be the end of the method. At least some JVM do collect such objects
before the end of the method.

Mark Thornton
Mark Space - 16 Apr 2008 19:02 GMT
> Yes, this is the exact method, copied and pasted, and the explanation
> I got was that it "clears up memory faster, because the garbage
[quoted text clipped - 5 lines]
>
> This isn't as bad as it gets.

I fear you're being taken for a ride.  Developer is charging for
un-maintainable code.  I'd cancel their contract immediately.

Sorry but that's what you get for going off shore.
Arne Vajhøj - 20 Apr 2008 03:00 GMT
> This isn't as bad as it gets.

Start writing your article for www.thedailywtf.com !

Arne
Abhijat Vatsyayan - 16 Apr 2008 23:58 GMT
> I have several developers who insist on using the following method,
> claiming that it helps reduce memory use by eliminating resources
[quoted text clipped - 13 lines]
>     }
> }
Just out of curiosity - is there another method named
closeResultSet(ResultSet rs)  which might look something like this  -

     try {
        rs.close() ;
         rs = null;
     } catch (Exception exp) {
         exp.printStackTrace();
     }
 }

If there is and if method "closeResultSetMetaData" was added after
method "closeResultSet", there might be an amusing explanation (no,
there still is no excuse for this!). Its possible that at one time all
developers were expected to explicitly close connections and streams
using these type of methods. Later on, developers blindly followed the
example without really understanding the intent (they assumed it was for
garbage collection but the name tells me otherwise). And since
ResultSetMetaData does not have a close() method, you are left with this
ridiculous code! Its rather amusing  and I would like to know what you
find out.

Also - don't these guys use logging (log4j/commons logging ... )?

Abhijat
Abhijat Vatsyayan - 17 Apr 2008 00:00 GMT
> I have several developers who insist on using the following method,
> claiming that it helps reduce memory use by eliminating resources
[quoted text clipped - 13 lines]
>     }
> }
Just out of curiosity - is there another method named
closeResultSet(ResultSet rs)  which might look something like this  -

     try {
        rs.close() ;
         rs = null;
     } catch (Exception exp) {
         exp.printStackTrace();
     }
 }

If there is and if method "closeResultSetMetaData" was added after
method "closeResultSet", there might be an amusing explanation (no,
there still is no excuse for this!). Its possible that at one time all
developers were expected to explicitly close connections and streams
using these type of methods. Later on, developers blindly followed the
example without really understanding the intent (they assumed it was for
garbage collection but the name tells me otherwise). And since
ResultSetMetaData does not have a close() method, you are left with this
ridiculous code! Its rather amusing  and I would like to know what you
find out.

Also - don't these guys use logging (log4j/commons logging ... )?
Roedy Green - 20 Apr 2008 08:30 GMT
On Wed, 16 Apr 2008 07:26:25 -0700 (PDT), Angry Moth Town
<bigdave.smith@gmail.com> wrote, quoted or indirectly quoted someone
who said :

>try {
>        rs = null;
>    } catch (Exception exp) {
>        exp.printStackTrace();

there is no exception possible from rs=null;

It will however free the associated object.  It is not usually
necessary for loca variables because you will usually exit the method
and all locals go out of scope within a millisecond anyway. However,
some methods are long running, and setting to null will indeed free
objects for potential later GC before the method terminates.

Signature

Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Gordon Beaton - 20 Apr 2008 10:12 GMT
> It will however free the associated object.

It will not. The calling method continues to hold a reference to it.

/gordon

--
Roedy Green - 20 Apr 2008 10:49 GMT
>It will not. The calling method continues to hold a reference to it.

It depends how it was created.  If it were passed as a parameter, the
caller may have created it as an expression, holding no handle to it
other than the passed parameter which can be nullified.

If it were created in the current method, the caller knows nothing
about it.

If the caller allocated it, pointed to it with its own local variable
and passed it as a parameter, than the callee nullifying the reference
would not do any good.

Happily nullifying a reference is a fairly quick operation.
Signature


Roedy Green Canadian Mind Products
The Java Glossary
http://mindprod.com

Gordon Beaton - 21 Apr 2008 07:56 GMT
> If it were created in the current method, the caller knows nothing
> about it.

It wasn't. Did you not read the thread?

> Happily nullifying a reference is a fairly quick operation.

However creating a method to do so is, as many others have already
pointed out in this thread, nonsense.

/gordon

--


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.