Resource leak: 'in' is never closed
Why does Eclipse give me the warming "Resource leak: 'in' is never closed" in the following code?
public void readShapeData() {
Scanner in = new Scanner(System.in);
System.out.println("Enter the width of the Rectangle: ");
width = in.nextDouble();
System.out.println("Enter the height of the Rectangle: ");
height = in.nextDouble();
Solution 1:
Because you don't close your Scanner
in.close();
Solution 2:
As others have said, you need to call 'close' on IO classes. I'll add that this is an excellent spot to use the try - finally block with no catch, like this:
public void readShapeData() throws IOException {
Scanner in = new Scanner(System.in);
try {
System.out.println("Enter the width of the Rectangle: ");
width = in.nextDouble();
System.out.println("Enter the height of the Rectangle: ");
height = in.nextDouble();
} finally {
in.close();
}
}
This ensures that your Scanner is always closed, guaranteeing proper resource cleanup.
Equivalently, in Java 7 or greater, you can use the "try-with-resources" syntax:
try (Scanner in = new Scanner(System.in)) {
...
}
Solution 3:
You need call in.close()
, in a finally
block to ensure it occurs.
From the Eclipse documentation, here is why it flags this particular problem (emphasis mine):
Classes implementing the interface java.io.Closeable (since JDK 1.5) and java.lang.AutoCloseable (since JDK 1.7) are considered to represent external resources, which should be closed using method close(), when they are no longer needed.
The Eclipse Java compiler is able to analyze whether code using such types adheres to this policy.
...
The compiler will flag [violations] with "Resource leak: 'stream' is never closed".
Full explanation here.
Solution 4:
It is telling you that you need to close the Scanner you instantiated on System.in
with Scanner.close()
. Normally every reader should be closed.
Note that if you close System.in
, you won't be able to read from it again. You may also take a look at the Console
class.
public void readShapeData() {
Console console = System.console();
double width = Double.parseDouble(console.readLine("Enter the width of the Rectangle: "));
double height = Double.parseDouble(console.readLine("Enter the height of the Rectangle: "));
...
}
Solution 5:
// An InputStream which is typically connected to keyboard input of console programs
Scanner in= new Scanner(System.in);
above line will invoke Constructor of Scanner class with argument System.in, and will return a reference to newly constructed object.
It is connected to a Input Stream that is connected to Keyboard, so now at run-time you can take user input to do required operation.
//Write piece of code
To remove the memory leak -
in.close();//write at end of code.