Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Closeable in garbage collection?

Does the close() method of the Closeable interface get called when the Closeable object is garbage collected ? [in java 6.0]

I have a static variable which is a resource(database connection). Since this is a static resource, there's no correct place to call the close() explicitly.

like image 994
raj Avatar asked Nov 30 '11 06:11

raj


1 Answers

The quick answer: no. GC does not care about Closeable at all.

Java does have protected void finalize() throws Throwable { } method which you can override — and it will be called on GC. It sort of works, e.g. in FileInputStream:

/**
 * Ensures that the <code>close</code> method of this file input stream is
 * called when there are no more references to it.
 *
 * @exception  IOException  if an I/O error occurs.
 * @see        java.io.FileInputStream#close()
 */
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);
        }
    }
}

Problem is, it creates more problems than it's worth: for example, JVM does not guarantee that it will ever call this method. That is, you should never use it for resource handling; what you see above is a safety net to make file handler leaks less damaging.

Yet another problem will be, static field will not be garbage collected—that is, as long as your class is visible. So you have no chance to use finalisation.

What you can do, though, is to use Runtime.addShutdownHook()—it will add yet another layer of safety nets to your application, giving you a chance to close the connection gracefully on exit. Given that you're using static field, the lifespan of your connection is likely to be the same as of JVM's, anyway.

I would recommend reviewing the approach, though.

like image 181
alf Avatar answered Oct 04 '22 12:10

alf