Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java -- Closing Scanner and Resource Leak

I'm learning Java and working on some projects for fun. One issue that I have run in to is that when I use a Scanner object Eclipse warns me that:

Resource Leak: 'scan' is never closed.

So, I added a scan.close(); at the end of my code and that takes care of the warning.

The problem comes in because I have other classes in the same package that also use scanner objects and and Eclipse tells me to close scanner in those classes respectively. However, when I do that it seems like it closes ALL of the scanner objects and I get errors during run time.

Here is an example of what causes the error:

import java.util.Scanner;
public class test2 {
    public static void main(String [] args) {
        Scanner scan = new Scanner(System.in);
        int test = 0;
        do {    
            //Do stuff
            test = scan.nextInt();
            System.out.println(test);

            scanTest scanTest = new scanTest();
            scanTest.test();
        } while (test != 0);

        scan.close();       
    }
}

import java.util.Scanner;
public class scanTest { 
    public void test() {
        Scanner scanner = new Scanner(System.in);
        int blah = scanner.nextInt();
        System.out.println(blah);
        scanner.close();
    }
}

After scanner is closed in the scanTest class and the do loop in test2 is entered again an error occurs at the line test = scan.nextInt();

I tried moving the creation of the scanner object into the do loop just to make a new object every time as well but the error still occurs.

Not sure why this is happening or how I can make sure all my I/O objects are closed out without running into problems.

One post I came across mentioned that when System.in is closed I cannot be re-opened. If this is the case would I just need to make sure a scanner object with System.in is closed at the very end of the program and @suppress all of the other scanner warnings in other classes? Or would that still leave all those scanner objects open (bad)?

like image 811
SuperCow Avatar asked May 13 '14 01:05

SuperCow


People also ask

Should you close scanner Java?

If you do not close the Scanner then Java will not garbage collect the Scanner object and you will have a memory leak in your program: void close(): closes the Scanner and allows Java to reclaim the Scanner's memory. You cannot re-use a Scanner so you should get rid of it as soon as you exhaust its input.

What does resource leak in Java mean?

In general, a Java memory leak happens when an application unintentionally (due to logical errors in code) holds on to object references that are no longer required. These unintentional object references prevent the built-in Java garbage collection mechanism from freeing up the memory consumed by these objects.

How do you close a scanner in Java?

close() method closes this scanner. If this scanner has not yet been closed then if its underlying readable also implements the Closeable interface then the readable's close method will be invoked.


2 Answers

First, this is no memory leak.

Second, when you close a stream wrapper, the default implementation is for it to close the stream that it wraps. This means that the first time you close your Scanner (as it is written), yes, you close System.in.

In general, one would like to avoid closing System.in if they were meaning to read from System.in again. The best way to go about this depends on your program.

One might copy the information from System.in into a buffer of some sort and then scan the buffer. One might not close the Scanner, reusing it in other locations. One might even de-reference the Scanner for garbage collection and create multiple new Scanners on System.in.

These solutions are not all equivalent, some are considered much better than others; but, it all depends on the calling program. Experiment with a few, and if you run into a problem, open a new StackOverflow question where you show the relevant portions of your code, a description of the problem, the example input, and the wrong output (along with the desired output).

Good luck.

like image 133
Edwin Buck Avatar answered Nov 06 '22 12:11

Edwin Buck


Yes, when you close a scanner you will be closing the underlying stream (in this case System.in). To avoid this, either create a global variable of scanner which can be used by all classes or have a central point for shutting down the scanner (just before the program exits would be ideal)

like image 43
Scary Wombat Avatar answered Nov 06 '22 10:11

Scary Wombat