Se eu tiver:
for (int i; i != 100; i++) { ArrayList myList = buildList(); //... more work here }
Eu tenho que definir myList para null no final do meu loop para obter o GC para recuperar a memory que ele usa para myList?
O GC limpará automaticamente todas as variables que não estiverem mais no escopo.
Uma variável declarada dentro de um bloco, como um loop for, somente estará no escopo dentro desse bloco. Uma vez que o código tenha saído do bloco, o GC irá removê-lo. Isso acontece assim que uma iteração do loop termina, portanto, a lista se torna elegível para a garbage collection assim que cada iteração do loop for concluída.
O escopo de uma variável também é porque i
não seria válido após o seu loop de exemplo.
Observe que esse é o caso apenas se você usar a variável somente dentro do loop. Se você passá-lo para outro método que mantém uma referência a ele, sua variável não será coletada como lixo.
Senhor, não! O GC do Java é muito, muito mais inteligente que isso.
Não, você não guia para o Java GC ou como funciona o Java GC
O GC recupera todas as instâncias inacessíveis, sempre que quiser. Não faz variables do GC.
As variables i
e myList
vivem na pilha. Quando o loop for termina (quando eles saem do escopo), eles serão empurrados da pilha e a memory recuperada. As variables então desaparecerão. Definindo a variável de referência myList
para null antes de desaparecer, realmente não faz diferença (para GCing as instâncias). Se o GC recuperar a memory da instância myList
referida, realmente depende se você tem outra referência à mesma instância.
Variáveis não recebem GCed, instâncias sim.
Isso provavelmente ajudaria a entender a syntax por trás do loop. Isso é discutido na Seção 14.14.1 do JLS .
BasicForStatement: for ( ForInitopt ; Expressionopt ; ForUpdateopt ) Statement ... Statement: StatementWithoutTrailingSubstatement ... StatementWithoutTrailingSubstatement: Block EmptyStatement ExpressionStatement ... Block: { BlockStatementsopt } BlockStatements: BlockStatement BlockStatements BlockStatement BlockStatement: LocalVariableDeclarationStatement ClassDeclaration Statement
Declaração, como sempre, pode ser uma única instrução ou um bloco (instruções cercadas por chaves). Um bloco representa um novo escopo léxico e as variables declaradas nele são locais apenas para esse bloco. O que muitas pessoas não percebem é que não é exclusivo do loop. Eu posso colocar uma instrução de bloco em qualquer lugar em um método:
public void someMethod() { { List myList = new ArrayList (); System.out.println(myList); } System.out.println(myList.size()); //compile error: myList out of scope }
De qualquer forma, isso não está indo onde eu estava pretendendo. É suficiente dizer que tem menos a ver com o fato de que é um loop e mais a ver com o fato de que é um bloco (se você optar por não usar uma instrução block, você não pode declarar novas variables locais, então o problema é irrelevante).
você não precisa se preocupar com o lixo. O Java GC fará isso automaticamente. Mas minha sugestão é que, como um bom desenvolvedor, você tem que praticar para libertar o lixo. Como o GC levará algum tempo de processamento. Então, cuidando de nós mesmos, vamos aumentar o desempenho.