Java的垃圾收集器会继续并处理循环中声明的变量吗?

时间:2010-10-18 15:12:41

标签: java garbage-collection

如果我有:

for (int i; i != 100; i++) {
    ArrayList<String> myList = buildList();
    //... more work here
}

我是否必须在循环结束时将myList设置为null以使GC回收它用于myList的内存?

5 个答案:

答案 0 :(得分:10)

GC将自动清除不再在范围内的任何变量。

在块中声明的变量(例如for循环)将仅在该块内的范围内。代码退出块后,GC将删除它。只要循环的迭代结束,就会发生这种情况,因此只要循环的每次迭代结束,列表就有资格进行垃圾收集。

变量的范围也是在示例循环后i无效的原因。

请注意,仅在循环内使用变量时才会出现这种情况。如果将其传递给另一个保持对它的引用的方法,则不会对您的变量进行垃圾回收。

答案 1 :(得分:5)

主啊,不! Java的GC很多,很多很多比这更聪明。

答案 2 :(得分:3)

GC会在需要时回收所有无法访问的实例。它不是GC变量。

变量imyList存在于堆栈中。当for循环结束时(当它们超出范围时),它们将被推入堆栈,因此它们的内存被回收。然后变量就会消失。在它消失之前将引用变量myList设置为null,实际上没有区别(对于GCing实例)。如果GC将回收引用的实例myList的内存,实际上取决于您是否有另一个对同一实例的引用。

变量没有得到GCed,实例也没有。

答案 3 :(得分:3)

理解for循环的语法可能会有所帮助。这在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

语句一如既往,可以是单个语句或块(用大括号括起来的语句)。块表示新的词法范围,其中声明的变量仅对该块是本地的。许多人没有意识到的是,这并不是for循环所特有的。我可以在方法中的任何地方放置一个块语句:

 public void someMethod() {

     {
         List<String> myList = new ArrayList<String>();
         System.out.println(myList);
     }
     System.out.println(myList.size()); //compile error: myList out of scope
 }

无论如何,这不是我打算去的地方。可以这么说,它与循环的关系较少,更多的是与它是块的事实有关(如果你选择不使用块语句,你不能声明新的局部变量,所以问题是无关)。

答案 4 :(得分:0)

你不必为垃圾烦恼。 Java GC将自动执行此操作。 但我的建议是,作为一名优秀的开发人员,你必须进行练习 释放垃圾。 因为GC会占用一些时间。 因此,通过照顾自己,我们将绝对提高性能。