Search code examples
javagarbage-collectionshutdownfinalize

Why do I need to call a close() or shutdown() method?


I'm new in Java with some background in C++ in my High School years. Now I'm trying to make something and I chose Java as the programming language.

I've done my homework and look a lot about "destructors" for Java, finalize() method, and close() or shutdown() methods. But still I think I don't have the idea of how this should work (more info below of course)

OK, the concrete question would be why do I need to call close() or shutdown() methods?

In my particular case I'm working with a class that I didn't develop that handles a smart card reader, but I've seen that the case of file management, where you have to call a close() method, would be similar.

Isn't calling a close() method the same idea as freeing memory in C++ (that sucks)? Meaning, I have to take care of the deletion or destruction of the object... isn't the GC for?

It could be an option that the class that I'm trying to use for the smart card reader is not the best, it might be better that this class implements the finalize() method so when is no longer used and ready for GC, frees memory (most probably is a native code) and/or frees hardware resources that the GC might not know how to do.

But what about the file management classes? Those are very used and maintained, why is still needed a close() method? I understand the purpose of existence, to unlock the file, but why do I have to remember to close it? Once the object is not used any more then unlock the file automatically, at least in the most common cases.

Finally, is it a proper workaround to wrap the class that needs to be closed or shutdown with a class that implements the finalize() method and there I call the close() or shutdown() method?

I've seen that the finalize() method is not very popular, so that is why I'm asking how this problem should be solved.

Thanks in advance

Juan

PS: what I've seen:

Is there a destructor for Java?

Why would you ever implement finalize()?

http://www.codeguru.com/java/tij/tij0051.shtml

explain the close() method in Java in Layman's terms

Do I need to close files I perform File.getName() on?


Solution

  • Most classes will clean up their external resources in their finalize methods, but this isn't analogous to C++'s destructor - a destructor is called as soon as an object is no longer used, but a finalizer isn't called until an object is garbage-collected, and you don't know when this is going to happen (and it might never happen if you don't have a memory-intensive program). So let's say you're allocating a bunch of objects that are each allocating a database connection (yes, you should be using connection pooling, but this is a hypothetical); you use each object and then null out its references so that it can be garbage-collected without first closing their database connections, and now your database is going to crap out on you because it's got too many connections open. You can call System.gc in the hopes that this will clean up the connections, but this is only a suggestion to the garbage-collector that it perform a collection, and it's possible that your garbage database connections' finalizers aren't smart enough to fully clean up the connections.

    Long story short, you need to call close and shutdown because you don't know if/when your objects' finalizers are going to run, and you don't know how good they are at cleaning up external resources.

    Incidentally, you should use try-catch-finally blocks to make sure you call close and shutdown - put the methods in the finally block. Or if you're using Java7, use try-with-resources.