Java - 是否需要关闭“new FileInputStream”?

时间:2012-01-26 20:28:55

标签: java

在此代码中:

Properties prop = new Properties();
prop.load(new FileInputStream("config.properties"));

某些属性已加载,但是fileinputstream是否需要关闭或者以某种方式处理它本身?

我是否需要创建变量,新文件输入流,然后关闭变量?

我也想知道,如果我创建一个变量,比如String a = nullint b; 当他们什么都没有时,他们会消耗内存吗?

如果我在方法或循环中有它,当它超出范围时它是否仍然消耗内存?

我认为有人曾经说过它已经加载到内存中而不是“活跃”了吗?

5 个答案:

答案 0 :(得分:3)

JVM很可能会快速垃圾收集并关闭FileInputStream。在一个小脚本中,这样做很好。然而,规范的习语是:

FileInputStream fis;
try {
    fis = new FileInputStream("config.properties");
    prop.load(fis);
} finally {
    fis.close();
}

对于变量,每个变量都是一个引用,即使它没有存储也会占用8个字节的内存(整数通常只占用4个字节,而且布尔值甚至更优化,但这些都是特殊情况)。一旦声明离开作用域,这些本地引用将不占用内存(因为它们的堆栈空间已经消失),但是您创建的任何对象都将存在,直到它们被垃圾回收。

答案 1 :(得分:1)

是的,你肯定需要自己关闭流。 我在这里指的是java文档: click!

  

此方法返回后,指定的流仍保持打开状态。

答案 2 :(得分:1)

关闭InputStreams总是更好(如果不是某些时间点那些将被GC,但我们不知道它什么时候会发生,这可能会导致很多问题)。

String a = null and int b

当您定义如上所述时,内存未在String情况下分配。

答案 3 :(得分:1)

Streams:是的。 Java没有析构函数,因此对象无法自行清理。一些清理工作是在垃圾收集时完成的(终结器),但依赖它并不是一个好的编程实践。

Java中存在“finally”块的原因之一是处理资源释放。

内存分配:看起来不是。我创建了以下程序:

public class deleteme
{
    public static void main( String[] args )
    {
        int a;
        String s;
    }

}

编译它,然后使用javap -c反编译,并得到:

public class deleteme {
  public deleteme();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: return
}

看起来没有什么事情真的发生,除了初始化我的主类。

然后我改变了代码说:

int a = 1;
String s = "";

编译,反编译并得到:

public class deleteme {
  public deleteme();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: iconst_1
       1: istore_1
       2: ldc           #2                  // String
       4: astore_2
       5: return
}

您可以清楚地看到分配内存的“main”方法中的其他说明。

我感觉Java编译器可能以不同的方式处理这些不同的版本。

答案 4 :(得分:0)

在一个问题中,这是很多问题:)

流应始终关闭,example

已为此提供了大量答案