raj
raj

Reputation: 3811

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.

Upvotes: 10

Views: 5345

Answers (4)

Perhaps you could use finalization?

Upvotes: 1

Muhammad Imran Tariq
Muhammad Imran Tariq

Reputation: 23352

if you don't close the connection , it will lead to connection memory leakage; unless until application server/web server is shut down. You can close all your connections by calling a custom close method or use finalilize

public void closeConnection {
        try { rs.close(); } catch (Exception e) { // TODO Auto-generated catch block }
        try { ps.close(); } catch (Exception e) { // TODO Auto-generated catch block }
        try { conn.close(); } catch (Exception e) { // TODO Auto-generated catch block }
    }

...

finally {
    try { rs.close(); } catch (Exception e) { // TODO Auto-generated catch block }
    try { ps.close(); } catch (Exception e) { // TODO Auto-generated catch block }
    try { conn.close(); } catch (Exception e) { // TODO Auto-generated catch block }
}

Upvotes: -1

alf
alf

Reputation: 8523

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.

Upvotes: 12

Snehal
Snehal

Reputation: 7496

It depends on the implementation of the "Closeable" interface, how it wants to handle garbage collection. FileInputStream for example, implements the Object#finalize() method, to call the Closeable#close() method.

Upvotes: 0

Related Questions