2

Will this method cause a memory leak when it throws an exception?

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);
    }
}

Is this better?

    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);
    }
}
user2997204
  • 1,344
  • 2
  • 12
  • 24

3 Answers3

3

A memory leak? No, once execution leaves this method, be it through return or throwing an exception, the BufferedWriter object will no longer be reachable, and becomes eligible for garbage collection.

However, as you are not invoking the close method when an exception is thrown while writing to the file, the file will remain open, preventing anybody from using it, and possibly exhausting the limited number of files that the operating system can keep open at any given time, until finally the garbage collector gets around to collecting the object, which will trigger its finalizer which closes the file, but you don't know when that is (it can easily take hours if you're unlucky). This is why operating system resources such as files should be closed right when your program no longer needs them. That's why InputStreams have a close method, and Java has a try-with-resources statement.

meriton
  • 68,356
  • 14
  • 108
  • 175
1

You should assume it does.

Close the writer in a finally block.

I think it's best to always be in the habit of using the finally block to close like so:

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) {
            }
        }
    }
}
Michael Krause
  • 4,689
  • 1
  • 21
  • 25
0

Nope , it will not cause a memory leak. The writer object will marked for garbage collection implicitly once the scope of the method ends. But it is a good practice to close the writer object so that the file in question gets closed too.

In cases where exception is thrown check in the finally block if the writer object is null or not. If it has been instantiated then close it . That is what we do in cases where a SQLException is thrown by the code using Jdbc so that the resources being used are released.

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

.

Chiseled
  • 2,280
  • 8
  • 33
  • 59