9

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.

Joshua Goldberg
  • 5,059
  • 2
  • 34
  • 39
raj
  • 3,769
  • 4
  • 25
  • 43
  • 2
    Are you sure the connection needs to be static? Public or private, declaring a connection as static does not add anything in a smaller application while adding needless complexity in larger ones; essentially you would need to make sure every access of that connection is thread safe. Sharing a single connection may sound like a good idea, not having to declare, setup and open a connection every time you do something however, that won't be the slow part. – phill Nov 30 '11 at 06:15
  • Agree. At least put the connection in a Singleton, might give you a better chance at future additions. – user949300 Nov 30 '11 at 06:33
  • Singleton isn't different from a static field in this context. It _is_ a static field, after all. – alf Nov 30 '11 at 06:38
  • Let me clarify. The "classic" Singleton held in a static field obviously doesn't work. But a class of which there exists, for now, only one instance, sometimes works for stuff like this, and could in the long run be expanded. Cause whenever marketing says "oh, we'll only need one of those mainwindows/DBs/websites" they are wrong. Now, this does beg the question of who holds that single reference.. :-) – user949300 Nov 30 '11 at 06:54
  • 1
    @user949300 as a matter of fact i've implemented it as a singleton class.. and it doesn't make any difference in this resource context. because, its just a connection and any number of client can access it in parallel. I dont think any lock mechanism is needed to make sure that only one client is "holding" the resource at any point in time. correct me if i'm wrong. – raj Nov 30 '11 at 09:25
  • 1
    @raj As far as I know, database connections were not implicitly designed to handle concurrency and there is talk about various problems because of that fact; A `ResultSet` is closed when a new statement is executed may be one of them. Even if it is thread safe, a single connection can only execute a single statement at a time, so any time more than one thread is executing at a time, someone is waiting. So there is still very little benefit to using a shared connection over a connection pool. Set up your connection pool in a singleton pattern and grab unique connections out of that. – phill Nov 30 '11 at 21:50

4 Answers4

10

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.

Community
  • 1
  • 1
alf
  • 8,377
  • 24
  • 45
1

Perhaps you could use finalization?

printomi
  • 43
  • 4
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • 2
    Problem is, static reference will make the object not eligible for collection—it's reachable, hence not a garbage. So `finalize` will not be called at all. – alf Nov 30 '11 at 06:20
  • I'd also claim that the link you provided is incorrect / out of date. It states "normally it (finalize) should be overridden to clean-up non-Java resources". Current best practice is to never override finalize(). – user949300 Nov 30 '11 at 06:39
0

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.

Snehal
  • 7,266
  • 2
  • 32
  • 42
-1

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 }
}
Muhammad Imran Tariq
  • 22,654
  • 47
  • 125
  • 190
  • 2
    Never ever ignore `Exception`. Ignoring `SQLException` here is pretty much ok and as expected; ignoring NPE is already a bad practice, as it could be done explicitly; ignoring any other exception means you miss possible bugs. – alf Nov 30 '11 at 06:23
  • 1
    Ignoring exception in a finally clause is common and, arguably good practice. – user949300 Nov 30 '11 at 06:47
  • You can catch or ignore it. //TODO – Muhammad Imran Tariq Nov 30 '11 at 07:17