Blocks within methods do not get their own stack frames; only methods do.
Each local variable is allocated at the method level and has a physical
scope of the entire method, even though its logical scope may be only a
small block within the method.
During the parts of the method outside of the logical scope, the local variable is said to be "invisible." See http:/ /java.sun.com/docs/books/performance/1st_edition/html/JPAppGC.fm.html#99741 4 for some official scoop on this.
I've been using the Jrockit 1.4.2_04 vm for a little while and I think it
actually nulls the references for you when they fall out of logical scope.
At least it seems this way because when I'm debugging, this is what I see
through variable watches.
Ron [b0b0b0b@gmail.com]
Doug,
Whilst I understand what you say to be true, could we instead, refactor in order to move the nested block into a private method and let the VM inline the call if it sees fit?
Simon [simon@redhillconsulting.com.au]
Take a look at this article: http://www-106.ibm.com/developerworks/library/j-
jtp01274.html.
It pretty much covers what you talk about and points
out that the whole premise behind nulling to help the GC may no longer hold
true.
Thank you for your comment. You are of course correct in that blocks inside a method will not get their own stack frame. My explination in this instance is a bit light. And, there are other things going on that I didn't mention. For example, the compiler may move the declaration of a variable to a broader scope. That said, the only way that I can see how nulling a variable would help GC is that it would release the reference earlier than it might otherwise do so. My point is that if you are "suddenly" release large number of objects, then I would suspect that there are some problems in the code. Improper scoping seems like one possible candidate. Certianly needing to null out variables is a code smell.
in response to Mark's trackback at
http://io.dnsalias.net/roller/comments/markwoon/Weblog/let_the_gc_be
My
premise is that you shouldn't have to help out the garbage collector. If
you do find yourself in a postion where you do have to "help", then you've
most likely done something wrong in your code. I've run into small number
of cases where the garbage collector legitimately could not keep up. These
cases do exists because after all, every system has a finite capacity. That
said, we do want to be wise in how we utilize that capacity.
Kirk: Completely agreed. I just wanted to clarify that putting the
variables in an anonymous block won't necessarily help. The only way it
would help is if the compiler puts in the "=null" that we just took out, as
Ron thinks that JRockit might do.
Simon: Yes, that would be the way to do what Kirk's talking about: refactor into a separate method. Unfortunately, if the compiler (or more likely the JIT) *does* inline the method call, you lose the automatic descoping of the stack frame. The compiler/JIT may or may not insert the "=null" back in for you -- I don't think that this is required.
I suspect that Simon has a particular interest in this topic, given his recent run-in with JUnit :-)
While setting the variable to null, we must always keep in mind that
somewhere down the line this might me used again and may throw NPE.
This would typically happen when the code is long and maintained by multiple developers. If you set the variable to null and then later use it, it will bomb. For example:
Car myCar = new Car(); Note: Even if you test run and test the
code, it will _appear_ to work, but say in customer place if that condition
becomes true, it will throw NPE. This would then require us to unit test
all the flow, which is practically
impossible. Kamal [ksinghdev@hotmail.com]
mCar.setColor(BLUE);
mCar
= null;
............
if (
{
int color = mCar.getColor();
}