If I have:
for (int i; i != 100; i++) {
ArrayList<String> myList = buildList();
//... more work here
}
Do I have to set myList to null at the end of my loop to get the GC to reclaim the memory it uses for myList?
If I have:
for (int i; i != 100; i++) {
ArrayList<String> myList = buildList();
//... more work here
}
Do I have to set myList to null at the end of my loop to get the GC to reclaim the memory it uses for myList?
The GC will automatically clean up any variables that are no longer in scope.
A variable declared within a block, such as a for loop, will only be in scope within that block. Once the code has exited the block, the GC will remove it. This happens as soon as an iteration of the loop ends, so the list becomes eligible for garbage collection as soon as each iteration of the loop finishes.
The scope of a variable is also why i
would not be valid after your example loop.
Note that this only is the case if you use the variable only within the loop. If you pass it to another method that keeps a reference to it, your variable will not be garbage collected.
you don't have to bother about the garbage. Java GC will automatically do this. But my suggestion is that as a good developer, you have to make practise for freeing the garbage. As GC will take some proccesing time. So by taking care of ourself we will definetly increase the performance.
The GC reclaims all unreachable instances, when ever it wants to. It does not GC variables.
The variables i
and myList
live on the stack. When the for loop ends(when they go out of scope), they will be pushed of the stack and so their memory reclaimed. The variables will then be gone. Setting the reference variable myList
to null just before it goes away, really makes no difference (for GCing the instances). If GC will reclaim the memory for the instance myList
referred too, really depends on whether you have another reference to the same instance.
Variables don't get GCed, instances do.
It would probably help to understand the syntax behind of the for-loop. That's discussed in the JLS Section 14.14.1.
BasicForStatement: for ( ForInitopt ; Expressionopt ; ForUpdateopt ) Statement ... Statement: StatementWithoutTrailingSubstatement ... StatementWithoutTrailingSubstatement: Block EmptyStatement ExpressionStatement ... Block: { BlockStatementsopt } BlockStatements: BlockStatement BlockStatements BlockStatement BlockStatement: LocalVariableDeclarationStatement ClassDeclaration Statement
Statement, as always, can be a single statement or a block (statements surrounded with curly braces). A block represents a new lexical scope and variables declared therein are local to that block only. What many people don't realize is that isn't unique to the for-loop. I can put a block statement anywhere in a method:
public void someMethod() {
{
List<String> myList = new ArrayList<String>();
System.out.println(myList);
}
System.out.println(myList.size()); //compile error: myList out of scope
}
Anyway this isn't going where I was intending. Suffice to say that it has less to do with the fact that it's a loop and more to do with the fact that it's a block (if you choose not to use a block statement, you can't declare new local variables so the problem is irrelevant).