2012-10-11 24 views
3

我与Eclipse朱诺工作,因为我写了下面的代码,Eclipse的警告我讲述了一个可能的内存泄漏:未分配的可封闭的流

String s = new Scanner(System.in).nextLine(); 

事实上,我从来没有关闭System.in流。 JVM(jre7)如何处理这个问题?这是一个很好的用途吗?

回答

3

这是虚惊一场,我相信。 Eclipse是用混淆的东西像这样:

String s = new Scanner(new FileReader("foo.txt")).nextLine(); 

每次泄漏一个新的可关闭你执行它。

但是在您的代码中,基础流(System.in)仍然可以使用。当然,没有需要从“资源泄漏”的角度关闭它。


事实上,我从来没有关闭System.in流。 JVM(jre7)如何处理这个问题?

System.in流保持打开,直到(大概)应用程序退出。但如果你一开始并没有打电话给new Scanner(System.in),情况也没有什么不同。

0

我的回答无效,详情请参阅评论。 OP,请接受另一个。

JVM将保持资源处于打开状态,直到您关闭它或程序退出。 Eclipse的警告看起来不错。在Java 7上,您可以使用try-with-resources模式:

try (Scanner scanner = new Scanner(System.in)) { 
    scanner.nextLine(); 
} 

这将在try块结束时自动关闭扫描器。

+1

你的代码示例是无用的,因为它不捕获'nextLine'的返回值。如果用'return scanner.nextLine();'方法封装了最干净的代码,就可以实现。还有一点:'Scanner'本身并没有获得任何资源,所以只要底层资源得到妥善管理,就没有任何伤害。在这种特殊情况下,伤害确实可以通过**关闭** stdin来完成。 OP的代码很好,Eclipse的警告错误放置。 –

+0

@MarkoTopolnik你是对的。我会投票将我的答案删除。 –

+0

最后一个提示,供参考:JVM在其管理对象为GC'd时也会关闭该资源,这可能在程序结束之前发生。 –

0

你可以放心地忽略这一点。

由于Scanner也是CloseableScanner::close也关闭底层的读者,如果这也是可关闭的。

以下是Scanner::close的代码。

public void close() { 
    if (closed) 
     return; 
    if (source instanceof Closeable) { 
     try { 
      ((Closeable)source).close(); 
     } catch (IOException ioe) { 
      lastException = ioe; 
     } 
    } 
    sourceClosed = true; 
    source = null; 
    closed = true; 
}