aspose file tools*
The moose likes Java in General and the fly likes Explicity making objects eligible for gc Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Java in General
Bookmark "Explicity making objects eligible for gc" Watch "Explicity making objects eligible for gc" New topic
Author

Explicity making objects eligible for gc

Ronnie Phelps
Ranch Hand

Joined: Mar 12, 2001
Posts: 329
In Java, it is good idea to explicitly assign null into a variable when no more in use because it can help the garbage collector whenever it runs.


:roll:
This is a quote that I have found in many places on the web. I'm sure this is true but my question for you guys is would this be neccessary for a Object that is local to a method? I'm assuming that it's obvious that an Object that is Declared and instantiated locally in a method will not be used again after the method returns.
Ernest Friedman-Hill
author and iconoclast
Marshal

Joined: Jul 08, 2003
Posts: 24187
    
  34

If a method is going to run for a long time, then it may be worthwhile to make sure object references you no longer need are nulled. But yes, just returning from the method is fine. I've seen code where people null a bunch of local variables, and then return -- it's silly, ugly, slow, cluttered, and pointless.


[Jess in Action][AskingGoodQuestions]
Rick O'Shay
Ranch Hand

Joined: Sep 19, 2004
Posts: 531
As a general rule setting variables to null is extremely poor form and that's putting it mildly. In specific cases it does make sense. Specifically, if you have "globally" scoped objects of considerable size or quantity, setting them to null might be prudent.
Michael Ernest
High Plains Drifter
Sheriff

Joined: Oct 25, 2000
Posts: 7292

Originally posted by Ronnie Phelps:

I'm assuming that it's obvious that an Object that is Declared and instantiated locally in a method will not be used again after the method returns.

Well, yes and no. In this minimal case, yes:

But let's say you pass this object reference to another method that refers to the object you passed in a broader scope:

And let's say that WYS objects hang around for a long time. So your creating method goes out of scope quickly and reaps the object reference. Your object in memory however sticks around so long as someone's using it.

Setting object references to null only guarantees that you've reduced the number of references to an object in memory by one.


Make visible what, without you, might perhaps never have been seen.
- Robert Bresson
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
With other words, even if it can be found in many places on the web, it simply is *not* true in the general case.


The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus
Ronnie Phelps
Ranch Hand

Joined: Mar 12, 2001
Posts: 329
Well to add to the question...does anyone know if the garbage collector runs if the main thread is sleeping?

Currently I have an app that's processing a huge amount of data and keeping primitive integers that store the count of data it finds. The app get's slower and slower as it processes more data.

If the garbage collector does run while a process is sleeping, do you think it would be possible for me to make my app faster by letting it sleep for a specific time interval after a certain amount of data has been processed?
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Ronnie Phelps:


:roll:
This is a quote that I have found in many places on the web. I'm sure this is true but my question for you guys is would this be neccessary for a Object that is local to a method? I'm assuming that it's obvious that an Object that is Declared and instantiated locally in a method will not be used again after the method returns.


Seems like lots of people don't understand the fundamentals of this issue. The quote is correct. And its _especially_ (dare I say only) true for variables local to methods. notwithstanding, its an implementation issue for particular JVMs and their GC algorithms.
Rick O'Shay
Ranch Hand

Joined: Sep 19, 2004
Posts: 531
Primitives and references are not on the heap so there's nothing to collect. Filling memory will not make your application slower unless it runs out, or starts thrashing: virtual memory starts paging heavily. You should add some instrumentation to find out where the bottleneck is.

JVMs are pretty good at distributing the collection effort over time but you can tune the GC to suit your needs. BTW, use Java 5.0 if you can. You get the bug fixes and performance improvements even if you generate 1.3 or 1.4 output code, and you certainly can do that.

http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
Ken Blair
Ranch Hand

Joined: Jul 15, 2003
Posts: 1078
Originally posted by Mr. C Lamont Gilbert:


Seems like lots of people don't understand the fundamentals of this issue. The quote is correct. And its _especially_ (dare I say only) true for variables local to methods. notwithstanding, its an implementation issue for particular JVMs and their GC algorithms.


As I understand it an Object becomes eligible for garbage collection once there are no more references to it in memory. Are there JVM's where the reference remains even after the method returns?
Rick O'Shay
Ranch Hand

Joined: Sep 19, 2004
Posts: 531
When you return from a method local references evaporate never to be seen again. Whether they referenced objects that are still reachable is another question and the GC is the one to answer that. It's very much implementation dependent.

This may be stretching things but I believe this is still a valid implementation of System.gc():

public static void gc() { /* burp */ }

Java makes no guarantee that an object will ever be collected.

Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

In this case, the "burp" comment was my best effort. Be thankful I even listened to the suggestion and didn't immediately assert because you had the nerve to call my gc() directly
[ September 16, 2005: Message edited by: Rick O'Shay ]
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Ken Blair:


As I understand it an Object becomes eligible for garbage collection once there are no more references to it in memory. Are there JVM's where the reference remains even after the method returns?


True, but Rick's points are valid. The GC has to evaluate whether or not an object is eligible. In general a GC when it gets a brief moment will make a brief effort. It can take more time to find out if certain references are not used. Setting some to null helps. I wouldn't call it worth it though. If you have any issue with the GC its best to address it through the JVM and not your code.
Tony Morris
Ranch Hand

Joined: Sep 24, 2003
Posts: 1608
Originally posted by Rick O'Shay:
As a general rule setting variables to null is extremely poor form and that's putting it mildly. In specific cases it does make sense. Specifically, if you have "globally" scoped objects of considerable size or quantity, setting them to null might be prudent.


Agreed (general poor form).
Another case is where you have an invisible reference, such that lack of explicit 'nullification' can result in a leak (under specific circumstances). The over-simplification that it's a general rule to set references to null as good form, is misleading, but it has allowed me a few trips to some exotic places to customer sites to remedy the problems caused by this fallacy (usually a poorly written web application on our application server), so I'll just sit back and watch .


Tony Morris
Java Q&A (FAQ, Trivia)
Norm Radder
Ranch Hand

Joined: Aug 10, 2005
Posts: 687
    
    1
An example of how to leave a reference to an unused object is to forget to remove listeners after having added them. The listener list will still have a reference to the unused object.
Voice of experience.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Mr. C Lamont Gilbert:
It can take more time to find out if certain references are not used. Setting some to null helps.


I'd think that a reference that doesn't exist any more also can't be used any longer. So I don't see the value in setting a local variable to null just before it vanishes, anyway.

Where do you get it from that it really does help?
Rick O'Shay
Ranch Hand

Joined: Sep 19, 2004
Posts: 531
>> It can take more time to find out if certain references are not used.

Not something you can ever be certain about and definitely not something you should ever design code around. What he's getting at is that objects tenure increases each time they survive a GC. Survivors are copied to an older section of the heap so that the nursery can be cleaned out each time the GC runs. If you set a reference to null you could untangle a knot that would allow the GC to recover that object sooner. I don't think a program exists or ever will exist that is optimized to the level where they need to start looking at issues like that.
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Ilja Preuss:


I'd think that a reference that doesn't exist any more also can't be used any longer. So I don't see the value in setting a local variable to null just before it vanishes, anyway.

Where do you get it from that it really does help?


The scenario is if you are using a local variable within a method it will be on the stack. Lets say you are 5 stack levels deep. Now you leave that method, go elsewhere, and into another method that is also 5 stack levels deep. Now you are actively using the same 5 stack level deep memory locations, but you have not used certain local variables yet. They just happen to be in the same slots as the old variables were.

So the GC sees that the memory address that a certain reference was being used from is still in use. It has to look closer to realize that its a new use. GC may not look that close for a while. Still, its guaranteed to look that close before out of memory exception is thrown. If that memory location had been null, it would be a no-brainer for the GC.
Ilja Preuss
author
Sheriff

Joined: Jul 11, 2001
Posts: 14112
Originally posted by Mr. C Lamont Gilbert:


The scenario is if you are using a local variable within a method it will be on the stack. Lets say you are 5 stack levels deep. Now you leave that method, go elsewhere, and into another method that is also 5 stack levels deep. Now you are actively using the same 5 stack level deep memory locations, but you have not used certain local variables yet. They just happen to be in the same slots as the old variables were.

So the GC sees that the memory address that a certain reference was being used from is still in use. It has to look closer to realize that its a new use. GC may not look that close for a while. Still, its guaranteed to look that close before out of memory exception is thrown. If that memory location had been null, it would be a no-brainer for the GC.


So you are saying that the first thing the GC does is looking at the memory location of a reference that is known to having once referenced an object, but not looking wether it's still the same reference? Sounds kind of strange to me, but what do I know...

If that's true (and I have no reason to believe that it couldn't be), I'd still advice not caring about it, for at least two reasons: the way to bet is that there are much more important things to care about that will have a much higher impact; and it is an optimization that highly depends on a specific implementation of the GC and might change with a different VM (as far as I know, it might even work significantly different wether you use the Sun VM with or without the -server switch).
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Yes. Its a good practice for the GC to clear the easily clearable references and work on the ones that require a bit more logic in a 2nd pass. You want the GC to be as fast as possible and there will only be an extremely small number of references that fall into this category.

I also suggest ignoring this behavior. its a sort of Fun Fact, but it should not have any bearing on the way you design your software.

In my programs I have a thread that waits for inactivity, then calls the GC. This is a way to prevent those long GC runs when it finally runs out of available memory or decides to take a big cleaning round. its been easier than trying to tweak the gc for me.
Rick O'Shay
Ranch Hand

Joined: Sep 19, 2004
Posts: 531
Originally posted by Mr. C Lamont Gilbert:
In my programs I have a thread that waits for inactivity, then calls the GC. This is a way to prevent those long GC runs when it finally runs out of available memory or decides to take a big cleaning round. its been easier than trying to tweak the gc for me.


This is what the JVM does so you are attempting to provide the same service. My money is on the JVM doing a better job of managing the heap that explicit calls to the garbage collector.

You are assuming it's waiting until it's out of memory before collecting and that's not the case � try monitoring the JVM head and you will see that. Moreover, if you want to distribute collection witha frequent period you can use the followign switch: -Xincgc
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

My work does not prevent the GC from doing its normal job. If the GC is getting all the references then my calls to gc() will take 0 time. However, we all know that these GCs get to a point where they have to run for like 20s to clear stuff. So I disagree with your assertion that they are so smart. The incremental GC is laughably slow.

All I want is normal GC operation without the periodic 20s stall out. calling the GC when the app is not being used is the best way to prevent this. Everyone should do it.
Rick O'Shay
Ranch Hand

Joined: Sep 19, 2004
Posts: 531
OK, let's say that despite being a core part of Java and a major focus of optimization over the years, the gc is laughable. You fixed the problem by calling their comical routine when your program is not busy. Two questions. How are you determining that it's not busy and how does calling the routine differ from the -Xingc designed specifically to distribute GC? Would't it be better to throw a switch? BTW, do you have data that shows the improvement you claim? What are you using to analyze the heap and the GC?
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

"-Xincgc
Enable the incremental garbage collector. The incremental garbage collector, which is off by default, will eliminate occasional garbage-collection pauses during program execution. However, it can lead to a roughly [b]10% decrease in overall GC performance[b/]"

Two admissions right there. That without incgc you get occasional pauses, and with it you loose performance. It matches what I see though its more like 30% decrease perhaps due to the limited memory on my laptop.

I only claim the incgc is laughable not the standard one, but the standard one adds those unsightly pauses. I run a simple timer to determine when the GUI is not busy. The incgc seems to perpetually run the gc, its too agressive. Im only trying to help the GC by suggesting opportunities for it to do its thing.
Steve Morrow
Ranch Hand

Joined: May 22, 2003
Posts: 657

The Truth About Garbage Collection
Reference Objects and Garbage Collection
Garbage collection and performance
Leonardo Postacchini
Greenhorn

Joined: Mar 30, 2004
Posts: 6
Setting references to null does not help anything and it is a Bad Pratice(TM), methods variables live in the stack along with the method that defined it. Once the method exits, that section of memory is cleaned and leaves no trace of the reference and thus it is no concern to the garbage collector and those references will not slow by any bit the collection.

About having two piles of methods in the same stack, and having references to diferent objects "confusing" the garbage collector, I would like to see some real data about that as on the stack there can be only one pile of methods, and a method is either pushed over an existing or an existing one is removed and the a new method is pushed in the cleaned space. There is no reference confusion, there is no two methods living in the same level.

About the Garbage collector being slow and calls to explicitly gc being able to optmize that, as was already pointed out, is absurd. Garbage collections are expensive and the more often they happen, the more inefective they are, for that reason the usual strategy is to as much as possible to execute garbage collection and this way execute them as few as it is possible(usually when the memory becomes full). That makes the cost of the garbage collection over cheaper, the flaw on this aproach is that when the collection happens it takes long. That can be bad on systems where you need to be responsive, thus the alternative algorithm is presented, allowing the JVM to collect when the system becomes idle, that does make the system to "seem" more responsive, as there is no freezes sometimes, but this aproach does consume more CPU processing.

In the end, there is no magic, at one extreme you have low cpu consuming algorithm with eventual freezes, at the other and you have cpu intensive algorithm wint no sensible freeze(unless you overloads the machine).

Even if your calls to gc does take efect(which is not guaranteed as per API documentation) you would just push the algorithm towards the processing ineficience with aparent better response.

And then, I would thrust the JVM implementation to do a good job on this, as it is written by experts on the subject, rather than on a programer making assumptions based on personal feelings and myths.
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Leonardo Postacchini:
Setting references to null does not help anything...


You seem to come in at the end rehasing many things covered already. Please start at the top. I tried to respond, but I would just be saying the same thing again.
Rick O'Shay
Ranch Hand

Joined: Sep 19, 2004
Posts: 531
Moreover, one of the key points made was that it does help to set variables to null in a variety of circumstances. Everybody agrees in general it's extremely poor form.
Rick O'Shay
Ranch Hand

Joined: Sep 19, 2004
Posts: 531
>> All I want is normal GC operation without the periodic 20s stall out.

http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

Originally posted by Rick O'Shay:
>> All I want is normal GC operation without the periodic 20s stall out.

http://java.sun.com/docs/hotspot/gc5.0/gc_tuning_5.html


I hear good things about 1.5. Just as soon as I get done with my current app I think Ill upgrade. Is 1.5 actually released yet?
Steve Morrow
Ranch Hand

Joined: May 22, 2003
Posts: 657

I hear good things about 1.5. Just as soon as I get done with my current app I think Ill upgrade. Is 1.5 actually released yet?

http://java.sun.com/j2se/1.5.0/download.jsp
Rick O'Shay
Ranch Hand

Joined: Sep 19, 2004
Posts: 531
It's been officially released for close to a year if not longer. Definitely worth switching for generics alone and when you add enums to the mix it gets very compelling. I recommend one of those Tiger introduction books that highlights all of the new features.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Almost. The official release was September 30, 2004. Prior to that were betas and the like.


"I'm not back." - Bill Harding, Twister
Rick O'Shay
Ranch Hand

Joined: Sep 19, 2004
Posts: 531
>> Almost. The official release was September 30, 2004.

Well excuuuuuuuuuuuuuuuuuuuuuse me Missed it by a week.
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Sorry, "Almost" was badly phrased there. I didn't mean you are almost right, I meant, it's been almost a year. Which is consistent with what you said in the first place.
Mr. C Lamont Gilbert
Ranch Hand

Joined: Oct 05, 2001
Posts: 1170

yea i read about the new features and played with it a bit, but don't want to switch horses (or mooses as it were ) mid-stream.

But I have started doing weird stuff in my program with expectation of using generics. Soon i suppose.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Explicity making objects eligible for gc