Java的垃圾收集器会继续并处理循环中声明的变量吗?
如果我有:
for (int i; i != 100; i++) { ArrayList myList = buildList(); //... more work here }
我是否必须在循环结束时将myList设置为null以使GC回收它用于myList的内存?
GC将自动清除不再在范围内的任何变量。
在块内声明的变量(例如for循环)将仅在该块内的范围内。 代码退出块后,GC将删除它。 只要循环的迭代结束,就会发生这种情况,因此只要循环的每次迭代结束,列表就有资格进行垃圾回收。
变量的范围也是i
在示例循环后无效的原因。
请注意,仅在循环内使用变量时才会出现这种情况。 如果将其传递给另一个保持对它的引用的方法,则不会对您的变量进行垃圾回收。
老兄,不! Java的GC比那更聪明。
不,您没有Java GC指南或Java GC的工作原理
GC会在需要时回收所有无法访问的实例。 它不是GC变量。
变量i
和myList
存在于堆栈中。 当for循环结束时(当它们超出范围时),它们将被推入堆栈,因此它们的内存被回收。 然后变量就会消失。 在它消失之前将引用变量myList
设置为null,实际上没有区别(对于GCing实例)。 如果GC将回收myList
引用的实例的内存,实际上取决于你是否有另一个对同一实例的引用。
实例没有GCed,GC实例。
它可能有助于理解for循环背后的语法。 这在JLS第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 myList = new ArrayList (); System.out.println(myList); } System.out.println(myList.size()); //compile error: myList out of scope }
无论如何,这不是我想要的地方。 可以说它与它是一个循环这一事实关系较少,而且更多地与它是一个块的事实有关(如果你选择不使用块语句,你不能声明新的局部变量,所以问题是无关)。
你不必为垃圾烦恼。 Java GC将自动执行此操作。 但我的建议是,作为一名优秀的开发人员,你必须进行实践以释放垃圾。 由于GC需要一些时间。 因此,通过照顾自己,我们将绝对提高性能。