Will stream classes or connections considered as a resource leak in Java

7.3k views Asked by At

Java has no lifetime for an object, this is managed by the garbage collector. And if I use some IO classes without closing it, or some DBConnection, will this considered a resource leak? In another words, will IO object be collected and destroyed by garbage collector, AFAIK, the garbage collector is for memory only. For example:

BufferedReader br = new BufferedReader( new FileReader( new File("path") ) );
3

There are 3 answers

3
Amar On BEST ANSWER

Yes you are right.

Garbage collection frees Java heap (memory) but close() frees OS resources used for open file (number of open files is limited on most system) and assures that the data is really written.

But many classes such as FileInputStream and RandomAccessFile are written with a finalize() method which ensures that IF an instance in garbage collected, close() will be called first. So in many cases, garbage collection does indirectly free up files, and it is often possible for programmers to be lazy about closing resources, because garbage collection usually cleans them up for you. Unfortunately.

The problem is that you can't control when this happens, and it may not happen at all. So if you have too many files open, the operating system may give you an error about that before the garbage collector gets around to closing them. Or if you want to move a file or delete it, immediately after reading it - the move or delete may fail, because at that moment you've still got the file open for reading.

Errors like this are often hard to reproduce reliably, because they depend on the timing of the garbage collector. So you get things which usually work fine, but sometimes fail mysteriously. Very annoying to debug. For this reason, it is stronly recommended to be sure to close() any stream/reader/connection or other closable resource you may be using, as soon as you are done with it. Preferably in a finally block, to ensure it happens even if some other error occurs in processing.

And with Java 7, there is an addition of AutoClosable interface, read more about it here.

Ref: http://www.coderanch.com/t/278165//java/InputStream-close-garbage-collection

2
Saj On

"Java has no lifetime for an object, this is managed by the garbage collector." -Not entirely true. It's firstly 'managed' by the way a program is written. If an object is out of scope, GC will most likely take care of it.

If you don't close br, it will live until the program exits unless collected by GC if ready for collection. It doesn't leak, just a long living variable.

0
Aniket Thakur On
And if I use some IO classes without closing it, or some DBConnection, will
this considered a resource leak?

Saying using same IO classes is wrong terminology. If you create a resource/connection and then use it's reference for some other resource without actually closing the original resource then if there are no active references to original resource then it will be eligible for GC.

However till the time that original resource is GCed all the OS resources (file handles etc) will not be freed. When the object will be subjected to GC(finalize() method is called on that object/resource) close() is called first due to which OS related resources are freed and then the heap memory.

For example consider FileInputStream finalize() method is as follows

protected void finalize() throws IOException {
    if ((fd != null) &&  (fd != FileDescriptor.in)) {

        /*
         * Finalizer should not release the FileDescriptor if another
         * stream is still using it. If the user directly invokes
         * close() then the FileDescriptor is also released.
         */
        runningFinalize.set(Boolean.TRUE);
        try {
            close();
        } finally {
            runningFinalize.set(Boolean.FALSE);
        }
    }
}

You see close() is called first.

So though GC takes care of memory management for you it is a good programming practice to close the resource in the finally statement when you don't need it.