此方法在抛出异常时是否会导致内存泄漏?

时间:2014-10-24 21:38:45

标签: java memory-leaks

此方法在抛出异常时是否会导致内存泄漏?

public static void warnUser(String name) {
    try {
        BufferedWriter writer = new BufferedWriter(new FileWriter(dir + "warnings.txt", true));
        writer.newLine();
        writer.write(name);
        writer.close();
    } catch (Exception e) {
        System.out.println(e.getMessage());
        System.err.println("error giving warning to: " + name);
    }
}

这样更好吗?

    public static void warnUser(String name) {
    try (BufferedWriter writer = new BufferedWriter(new FileWriter(dir + "warnings.txt", true))) {
        writer.newLine();
        writer.write(name);
    } catch (Exception e) {
        System.out.println(e.getMessage());
        System.err.println("error giving warning to: " + name);
    }
}

3 个答案:

答案 0 :(得分:3)

内存泄漏?不,一旦执行离开此方法,无论是通过返回还是抛出异常,BufferedWriter对象将不再可访问,并且有资格进行垃圾回收。

但是,由于在写入文件时抛出异常时没有调用close方法,文件将保持打开状态,阻止任何人使用它,并可能耗尽操作系统可以保留的有限数量的文件在任何给定的时间打开,直到最后垃圾收集器到处收集对象,这将触发关闭文件的终结器,但你不知道什么时候(如果你不幸的话,它可能很容易需要几个小时)。这就是为什么在程序不再需要时应该关闭文件等操作系统资源的原因。这就是为什么InputStreams有一个close方法,而Java有一个try-with-resources语句。

答案 1 :(得分:1)

你应该假设它。

在finally块中关闭writer。

我认为最好总是养成使用finally块关闭的习惯:

public static void warnUser(String name) {
    BufferedWriter writer = null;

    try {
        writer = new BufferedWriter(new FileWriter(dir + "warnings.txt", true));
        writer.newLine();
        writer.write(name);
    } catch (Exception e) {
        System.out.println(e.getMessage());
        System.err.println("error giving warning to: " + name);
    } finally {
        if (writer != null) {
            try {
                writer.close();
            } catch (IOException e) {
            }
        }
    }
}

答案 2 :(得分:0)

不,它不会导致内存泄漏。一旦方法的范围结束,writer对象将隐式标记为垃圾收集。但是关闭writer对象是一个很好的做法,这样有问题的文件也会被关闭。

如果抛出异常,如果writer对象为null,则检查finally块。如果它已被实例化,则关闭它。这就是我们在使用Jdbc的代码抛出SQLException以便释放正在使用的资源时所做的事情。

finally
{ 
  if (writer!= null) 
  { 
    try {
            writer.close();
        } 
    catch (IOException exception2) 
        {
          // Do Nothing
        }
  }
}