Should AutoCloseable Iterator to a ResultSet call close from finalizer? - java

I have an Iterator backed by a ResultSet. I need that for a row-level post-processing. The iterator implements AutoCloseable inteface.
The connection remains open up until we iterate through all the rows / iteration interrupted by the user. And everything is fine if the consumer of the iterator calls close() method explicitly or is wrapping the use of the iterator in a Java7 try block. However, if the consumer doesn't do so I can't guarantee that the connection will be returned to the pool. In C# world we would do a finalizer and call Dispose(bool) from the finalizer as a fallback option. Should we do the same in Java?

This kind of cleanup generally isn't done in a Java finalize() method. Failing to ensure proper disposal of a resource is a programming error; trying to clean up after bad programming is enabling the continuation of bad practices.
What is more common is a debugging option to help developers who've acknowledged they have a problem. Usually this isn't enabled by default, because of the overhead involved, but when the right flag is turned on, a stack trace is created when the resource is allocated. If finalize() is invoked without the resource being destroyed properly, the stack is logged to show the location of the leak.
There are a number of caveats around finalize(), and you should generally avoid it. One of the main problems in this case is that there's no guarantee it will ever be invoked, and even if it is, it may not be in time to help.

Related

what is the proper way to close streams on java's exec?

After
Runtime.getRuntime().exec(command);
i see syscalls happening that show 2~3 file descriptors (FIFO pipes). What is the proper way to close them with try-with-resource pattern?
Most historical tribal knowledge found on java forums suggest:
# out of date!
... } finally {
IOUtils.closeQuietly(p.getOutputStream());
IOUtils.closeQuietly(p.getInputStream());
IOUtils.closeQuietly(p.getErrorStream());
}
but that doesn't sound right because 1) method closeQuietly is deprecated and most libraries suggest using try-with-resource, 2) it is inelegant as I might not necessarily have all streams.
And simply moving the exec() call into try feels wrong as it is not the resource i will call close() on.
Closing them isn't necessary; the close by themselves when the process dies. If the process never dies, it is also not neccessary: Either you make a new never-dying process every so often in which case your system is going to crash and run out of resources whether you close these or not, or you make it only once, in which case these resources aren't going to count for much. For what it is worth, these are quite lightweight resources, and often they simply cannot be 'closed' in the sense that the resources can be 'freed' - closing them either keeps them open but denies further chat (and sends EOFs where needed), or reroutes them to /dev/null; generally processes just have 3 pipes on em and will continue to have them until the process dies.
Yes, closeQuietly is a silly idea for virtually all purposes, and so it is here. If closing these streams somehow fail you probably don't want to silently ignore that.
If you must close them, the individual streams from these 3 are closable. However, note that you're reading rules of thumb and attempting to apply them as if they are gospel truth. try-with-resources is not always the right answer, and try-with-resources is not a 100% always replacement for close, let alone closeQuietly.
For example, try-with-resources specifically is designed around a period of usage. You declare the span of statements within which the resource should be available (the braces that go with the try block), and the construct will then ensure that the resource is closed only once code flow transitions out of that span of statements, no matter how it exits this. That makes it probably irrelevant here, too!
You are starting a long-lived process and don't care about the in/out. You just want the process to run and to keep running. This means there is no span at all, and you should just call close() on these if somehow you feel it is important to try to save the resources even though most likely this accomplishes nothing at all. No span-of-statements means try-with-resources isn't right.
You are starting a short-lived process that you interact with. The right thing to 'close' is the process itself, except you can't use try-with-resources for that. That can only be used on auto-closables. (resources where the class that represents them implement AutoClosable. Most do, some don't. Lock is a famous one. Process is another: To 'close' it, you invoke destroy() or even destroyForcibly(). You cannot use try-with-resources (not without ugly hacks that defeats the purpose) to do this! Once you close/destroy the process, the streams that went along with them are dead too.
More generally the principle is: If you create it, you close it. If you never call getOutputStream() you never created them. On some OSes, fetching these streams and then closing them wastes more resources than not doing this. Thus, if the argument is based on some sort of purity model, then you shouldn't close them either. If it's based on pragmatics, you'd have to test how heavy these resources really are (most likely, extremely light), whether closing them actually saves you some pipes (most likely, it will not), and whether close()-ing the result of invoking getOutputStream() on the process even helps if the answers to the above questions make that relevant (it probably will, but the spec does not guarantee this).
They are very light processes that in almost every case don't require closing...

Is it possible to run code when the object in WeakReference is garbage collected? [duplicate]

Is there a destructor for Java? I don't seem to be able to find any documentation on this. If there isn't, how can I achieve the same effect?
To make my question more specific, I am writing an application that deals with data and the specification say that there should be a 'reset' button that brings the application back to its original just launched state. However, all data have to be 'live' unless the application is closed or reset button is pressed.
Being usually a C/C++ programmer, I thought this would be trivial to implement. (And hence I planned to implement it last.) I structured my program such that all the 'reset-able' objects would be in the same class so that I can just destroy all 'live' objects when a reset button is pressed.
I was thinking if all I did was just to dereference the data and wait for the garbage collector to collect them, wouldn't there be a memory leak if my user repeatedly entered data and pressed the reset button? I was also thinking since Java is quite mature as a language, there should be a way to prevent this from happening or gracefully tackle this.
Because Java is a garbage collected language you cannot predict when (or even if) an object will be destroyed. Hence there is no direct equivalent of a destructor.
There is an inherited method called finalize, but this is called entirely at the discretion of the garbage collector. So for classes that need to explicitly tidy up, the convention is to define a close method and use finalize only for sanity checking (i.e. if close has not been called do it now and log an error).
There was a question that spawned in-depth discussion of finalize recently, so that should provide more depth if required...
Have a look at the try-with-resources statement. For example:
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
System.out.println(br.readLine());
} catch (Exception e) {
...
} finally {
...
}
Here the resource that is no longer needed is freed in the BufferedReader.close() method. You can create your own class that implements AutoCloseable and use it in a similar fashion.
This statement is more limited than finalize in terms of code structuring, but at the same time it makes the code simpler to understand and maintain. Also, there is no guarantee that a finalize method is called at all during the livetime of the application.
Nope, no destructors here. The reason is that all Java objects are heap allocated and garbage collected. Without explicit deallocation (i.e. C++'s delete operator) there is no sensible way to implement real destructors.
Java does support finalizers, but they are meant to be used only as a safeguard for objects holding a handle to native resources like sockets, file handles, window handles, etc. When the garbage collector collects an object without a finalizer it simply marks the memory region as free and that's it. When the object has a finalizer, it's first copied into a temporary location (remember, we're garbage collecting here), then it's enqueued into a waiting-to-be-finalized queue and then a Finalizer thread polls the queue with very low priority and runs the finalizer.
When the application exits, the JVM stops without waiting for the pending objects to be finalized, so there practically no guarantees that your finalizers will ever run.
Use of finalize() methods should be avoided. They are not a reliable mechanism for resource clean up and it is possible to cause problems in the garbage collector by abusing them.
If you require a deallocation call in your object, say to release resources, use an explicit method call. This convention can be seen in existing APIs (e.g. Closeable, Graphics.dispose(), Widget.dispose()) and is usually called via try/finally.
Resource r = new Resource();
try {
//work
} finally {
r.dispose();
}
Attempts to use a disposed object should throw a runtime exception (see IllegalStateException).
EDIT:
I was thinking, if all I did was just
to dereference the data and wait for
the garbage collector to collect them,
wouldn't there be a memory leak if my
user repeatedly entered data and
pressed the reset button?
Generally, all you need to do is dereference the objects - at least, this is the way it is supposed to work. If you are worried about garbage collection, check out Java SE 6 HotSpot[tm] Virtual Machine Garbage Collection Tuning (or the equivalent document for your JVM version).
With Java 1.7 released, you now have the additional option of using the try-with-resources block. For example,
public class Closeable implements AutoCloseable {
#Override
public void close() {
System.out.println("closing...");
}
public static void main(String[] args) {
try (Closeable c = new Closeable()) {
System.out.println("trying...");
throw new Exception("throwing...");
}
catch (Exception e) {
System.out.println("catching...");
}
finally {
System.out.println("finalizing...");
}
}
}
If you execute this class, c.close() will be executed when the try block is left, and before the catch and finally blocks are executed. Unlike in the case of the finalize() method, close() is guaranteed to be executed. However, there is no need of executing it explicitly in the finally clause.
I fully agree to other answers, saying not to rely on the execution of finalize.
In addition to try-catch-finally blocks, you may use Runtime#addShutdownHook (introduced in Java 1.3) to perform final cleanups in your program.
That isn't the same as destructors are, but one may implement a shutdown hook having listener objects registered on which cleanup methods (close persistent database connections, remove file locks, and so on) can be invoked - things that would normally be done in destructors.
Again - this is not a replacement for destructors but in some cases, you can approach the wanted functionality with this.
The advantage of this is having deconstruction behavior loosely coupled from the rest of your program.
No, java.lang.Object#finalize is the closest you can get.
However, when (and if) it is called, is not guaranteed.
See: java.lang.Runtime#runFinalizersOnExit(boolean)
I agree with most of the answers.
You should not depend fully on either finalize or ShutdownHook
finalize
The JVM does not guarantee when this finalize() method will be invoked.
finalize() gets called only once by GC thread. If an object revives itself from finalizing method, then finalize will not be called again.
In your application, you may have some live objects, on which garbage collection is never invoked.
Any Exception that is thrown by the finalizing method is ignored by the GC thread
System.runFinalization(true) and Runtime.getRuntime().runFinalization(true) methods increase the probability of invoking finalize() method but now these two methods have been deprecated. These methods are very dangerous due to lack of thread safety and possible deadlock creation.
shutdownHooks
public void addShutdownHook(Thread hook)
Registers a new virtual-machine shutdown hook.
The Java virtual machine shuts down in response to two kinds of events:
The program exits normally, when the last non-daemon thread exits or when the exit (equivalently, System.exit) method is invoked, or
The virtual machine is terminated in response to a user interrupt, such as typing ^C, or a system-wide event, such as user logoff or system shutdown.
A shutdown hook is simply an initialized but non-started thread. When the virtual machine begins its shutdown sequence it will start all registered shutdown hooks in some unspecified order and let them run concurrently. When all the hooks have finished it will then run all uninvoked finalizers if finalization-on-exit has been enabled.
Finally, the virtual machine will halt. Note that daemon threads will continue to run during the shutdown sequence, as will non-daemon threads if the shutdown was initiated by invoking the exit method.
Shutdown hooks should also finish their work quickly. When a program invokes exit the expectation is that the virtual machine will promptly shut down and exit.
But even Oracle documentation quoted that
In rare circumstances the virtual machine may abort, that is, stop running without shutting down cleanly
This occurs when the virtual machine is terminated externally, for example with the SIGKILL signal on Unix or the TerminateProcess call on Microsoft Windows. The virtual machine may also abort if a native method goes awry by, for example, corrupting internal data structures or attempting to access nonexistent memory. If the virtual machine aborts then no guarantee can be made about whether or not any shutdown hooks will be run.
Conclusion : use try{} catch{} finally{} blocks appropriately and release critical resources in finally(} block. During release of resources in finally{} block, catch Exception and Throwable.
First, note that since Java is garbage-collected, it is rare to need to do anything about object destruction. Firstly because you don't usually have any managed resources to free, and secondly because you can't predict when or if it will happen, so it's inappropriate for things that you need to occur "as soon as nobody is using my object any more".
You can be notified after an object has been destroyed using java.lang.ref.PhantomReference (actually, saying it has been destroyed may be slightly inaccurate, but if a phantom reference to it is queued then it's no longer recoverable, which usually amounts to the same thing). A common use is:
Separate out the resource(s) in your class that need to be destructed into another helper object (note that if all you're doing is closing a connection, which is a common case, you don't need to write a new class: the connection to be closed would be the "helper object" in that case).
When you create your main object, create also a PhantomReference to it. Either have this refer to the new helper object, or set up a map from PhantomReference objects to their corresponding helper objects.
After the main object is collected, the PhantomReference is queued (or rather it may be queued - like finalizers there is no guarantee it ever will be, for example if the VM exits then it won't wait). Make sure you're processing its queue (either in a special thread or from time to time). Because of the hard reference to the helper object, the helper object has not yet been collected. So do whatever cleanup you like on the helper object, then discard the PhantomReference and the helper will eventually be collected too.
There is also finalize(), which looks like a destructor but doesn't behave like one. It's usually not a good option.
The finalize() function is the destructor.
However, it should not be normally used because it is invoked after the GC and you can't tell when that will happen (if ever).
Moreover, it takes more than one GC to deallocate objects that have finalize().
You should try to clean up in the logical places in your code using the try{...} finally{...} statements!
If it's just memory you are worried about, don't. Just trust the GC it does a decent job. I actually saw something about it being so efficient that it could be better for performance to create heaps of tiny objects than to utilize large arrays in some instances.
Perhaps you can use a try ... finally block to finalize the object in the control flow at which you are using the object. Of course it doesn't happen automatically, but neither does destruction in C++. You often see closing of resources in the finally block.
There is a #Cleanup annotation in Lombok that mostly resembles C++ destructors:
#Cleanup
ResourceClass resource = new ResourceClass();
When processing it (at compilation time), Lombok inserts appropriate try-finally block so that resource.close() is invoked, when execution leaves the scope of the variable. You can also specify explicitly another method for releasing the resource, e.g. resource.dispose():
#Cleanup("dispose")
ResourceClass resource = new ResourceClass();
The closest equivalent to a destructor in Java is the finalize() method. The big difference to a traditional destructor is that you can't be sure when it'll be called, since that's the responsibility of the garbage collector. I'd strongly recommend carefully reading up on this before using it, since your typical RAIA patterns for file handles and so on won't work reliably with finalize().
Just thinking about the original question... which, I think we can conclude from all the other learned answers, and also from Bloch's essential Effective Java, item 7, "Avoid finalizers", seeks the solution to a legitimate question in a manner which is inappropriate to the Java language...:
... wouldn't a pretty obvious solution to do what the OP actually wants be to keep all your objects which need to be reset in a sort of "playpen", to which all other non-resettable objects have references only through some sort of accessor object...
And then when you need to "reset" you disconnect the existing playpen and make a new one: all the web of objects in the playpen is cast adrift, never to return, and one day to be collected by the GC.
If any of these objects are Closeable (or not, but have a close method) you could put them in a Bag in the playpen as they are created (and possibly opened), and the last act of the accessor before cutting off the playpen would be to go through all the Closeables closing them... ?
The code would probably look something like this:
accessor.getPlaypen().closeCloseables();
accessor.setPlaypen( new Playpen() );
closeCloseables would probably be a blocking method, probably involving a latch (e.g. CountdownLatch), to deal with (and wait as appropriate for) any Runnables/Callables in any threads specific to the Playpen to be ended as appropriate, in particular in the JavaFX thread.
Many great answers here, but there is some additional information about why you should avoid using finalize().
If the JVM exits due to System.exit() or Runtime.getRuntime().exit(), finalizers will not be run by default. From Javadoc for Runtime.exit():
The virtual machine's shutdown sequence consists of two phases. In the first phase all registered shutdown hooks, if any, are started in some unspecified order and allowed to run concurrently until they finish. In the second phase all uninvoked finalizers are run if finalization-on-exit has been enabled. Once this is done the virtual machine halts.
You can call System.runFinalization() but it only makes "a best effort to complete all outstanding finalizations" – not a guarantee.
There is a System.runFinalizersOnExit() method, but don't use it – it's unsafe, deprecated long ago.
If you got the chance of using a Contexts and Dependency Injection (CDI) framework such as Weld you can use the Java annotation #Predestroy for doing cleanup jobs etc.
#javax.enterprise.context.ApplicationScoped
public class Foo {
#javax.annotation.PreDestroy
public void cleanup() {
// do your cleanup
}
}
Though there have been considerable advancements in Java's GC technology, you still need to be mindful of your references. Numerous cases of seemingly trivial reference patterns that are actually rats nests under the hood come to mind.
From your post it doesn't sound like you're trying to implement a reset method for the purpose of object reuse (true?). Are your objects holding any other type of resources that need to be cleaned up (i.e., streams that must be closed, any pooled or borrowed objects that must be returned)? If the only thing you're worried about is memory dealloc then I would reconsider my object structure and attempt to verify that my objects are self contained structures that will be cleaned up at GC time.
If you're writing a Java Applet, you can override the Applet "destroy()" method. It is...
* Called by the browser or applet viewer to inform
* this applet that it is being reclaimed and that it should destroy
* any resources that it has allocated. The stop() method
* will always be called before destroy().
Obviously not what you want, but might be what other people are looking for.
No Java doesn't have any destructors .The main reason behind it in Java is the Garbage Collectors that passively works in the background always and all the objects are made in the heap memory , that is the place where GC works .In c++ there we have to explicitly call the delete function since there is no Garbage collector like thing.
In Java, the garbage collector automatically deletes the unused objects to free up the memory. So it’s sensible Java has no destructors available.
Try calling the onDestroy() method when it comes to android programming. This is the last method that executed just before the Activity/Service class is killed.
Missing form all the answers I just scanned is the safer replacement for finalizers. All of the other answers are correct about using try-with-resources and avoiding finalizers as they are unreliable and are now deprecated...
However they haven't mentioned Cleaners. Cleaners were added in Java 9 to explicitly handle the job of cleanup in a better way than finalizers.
https://docs.oracle.com/javase/9/docs/api/java/lang/ref/Cleaner.html
I used to mainly deal with C++ and that is what lead me to the search of a destructor as well. I am using JAVA a lot now. What I did, and it may not be the best case for everyone, but I implemented my own destructor by reseting all the values to either 0 or there default through a function.
Example:
public myDestructor() {
variableA = 0; //INT
variableB = 0.0; //DOUBLE & FLOAT
variableC = "NO NAME ENTERED"; //TEXT & STRING
variableD = false; //BOOL
}
Ideally this won't work for all situations, but where there are global variables it will work as long as you don't have a ton of them.
I know I am not the best Java programmer, but it seems to be working for me.

Why are some some resources in Java not garbage collected and must be closed or autoclosed?

If you are lucky some of these classes implement AutoClosable but sometimes you just have to be careful and inspect the existing methods to notice that there is a close, destroy or shutdown method (or what ever the author decided to name it).
This is a major source of resource leaks in Java.
I was discussing this with a colleague and wondered too: why can this not be automated in some way ?
In theory you can use finalize for such cases, but it is not recommended. So why is there no way to just use some of those closable resources and let the GC autoclose them when the instance is no longer reachable without having to remember to explicitely write some close handling code (like try ...) ?
Is this because the system may have been resource starved (File descriptors, ...) before the GC kicks in ?
NOTE: I use autoclose when possible and check my code for memory leaks using FindBugs (+ FB contrib), but still, I wonder ...
Also of interest (as discussed in the answers): deprecation of finalize.
The Garbage Collector's only job is to collect memory that is no longer used. Adding closing of resources will have negative effects on the performance of the Garbage Collector and is currently done by the Finalizer thread that is called by the Garbage Collector anyway in order to allow implementations to clear resources before being collected. It's worth noting that this mechanism is declared deprecated because it wasn't the best solution for this kind of thing from the start, but for the time being it's possible to implement your classes to clean themselves up before they are going to be collected.
The Finalizer (or the new mechanim in Java 9) might be extended to check if the class to be collected implements AutoClosable (an interface added with Java 1.7, so it's not that old anyway) and call it in addition to finalize. This would have a similar effect as you proposed without the need to change the behavior and the role of the Garbage Collector. Maybe that's already happening (haven't tested it myself, yet).
why this cannot be automated in some way ?
Because, in general, a class can do anything: there is no easy way for the compiler to know that something was "opened", and thus should be "closed", because Java has no strong notion of ownership of values.
Even if you have a field which is of a type that needs closing, you can't easily guarantee that it won't be returned from a getter, say, to something else which is responsible for closing it.
The only really consistent way to indicate that instances of a class need closing is by implementing the AutoCloseable interface (or Closeable, or some other interface which extends it). If you're using these, IDEs may be able to provide warnings about leaked resources; but these are going to be on a best-effort basis.
You can create your own auto-close resource if you like, but you will need to put in a little work.
You could code a manager/factory class that keeps a weak reference to an object representing each closable object. You hand out this "Representative" facade class to clients and the client uses this representative class to access the resource (It would contain a reference to the closable and act as a delegate).
This implies that the factory starts a thread and keeps a map of:
<WeakReference<Representative>, Closable>
that it can iterate over. If the representative has been garbage collected (the WeakReference would return a null), close the closable and remove it from the map--Anything left in the collection can also be closed on VM shutdown with a hook--This is probably the most dangerous part since a thread could still be interacting with the Closable during shutdown, but we have all the tools to manage the problem.
Your closable resource itself is never held by anything outside it's Representative and the Manager/Factory so it's behavior is predictable.
I've never seen this done--probably because it seems like a lot more work than just making an object "Closable" (and would be much easier to implement incorrectly), but I don't know why it wouldn't work.
It would be quite difficult for Java to implement this as a pattern/language feature, but by giving us the WeakReference it gives us the tools to make it possible.
To me it looks like all the answers are missing the main point: While the GC can take care of the resource closing, it can't do it fast enough.
An example is the rather unsolved problem of memory mapped files. They mapping get cleared when they're no more references to them, but in the meantime, you may run out of file descriptors or virtual memory (this indeed can happen as it's limited to a few TB).
The GC gets only invoked when the heap memory is exhausted, which may be long after other resources are exhausted.
It's impossible to efficient collect garbage as soon as an object becomes unreachable. This would require reference counting, which is way slower than generational GC and requires some additional treatment for circular references.
It's impossible to efficiently collect resources in some separated GC cycles, so that resource closing works fast enough.
This is why IMHO this answer is wrong. You can handle resources this way (or using finalize or whatever), but it's not good enough.
If you are developing a common module(or a common util class), you can use execute around method pattern to handle resources that needs to be closed. So this way users of your module don't have handle these resource's closing.(Probably prevents many bugs, because people may forget to close the resource.)
There is a great presentation by Mr Venkat, that he talks about this problem. Watch the next 10 minute, he explains this beautifully.https://youtu.be/e4MT_OguDKg?t=49m48s
Here is the sample code from the presentation;
public class Resource {
/*
* This represents a resource that needs to be closed.
* Since opening and closing the resource are done through use() method,
* Users of this resource don't have to care about resource is being closed or not.
* They just have to pass operations that they want to execute on the resource.
*/
private Resource() {System.out.println("created..");}
public Resource op1() {System.out.println("op1");return this;}
public Resource op2() {System.out.println("op2");return this;}
private void close() {System.out.println("closed..");}
public static void use(Consumer<Resource> consumer) {
Resource resource = new Resource();
try {
consumer.accept(resource);
}
finally {
resource.close();
}
}
}
public class SampleResourceUser {
/*
* This represents the user of the Resource,
* User only cares about which operations that needs to be done on the resource.
* Opening and closing the resource wrapped around the operation methods by the owner of the Resource.
*
*/
public static void main(String[] args) {
Resource.use(resource->resource.op1().op2());
}
}

Is it possible for try-with-resource to fail to close resources?

As per Oracle documentation
The try-with-resources statement is a try statement that declares one or more resources. A resource is as an object that must be closed after the program is finished with it. The try-with-resources statement ensures that each resource is closed at the end of the statement. Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource
If a resource does not implement AutoCloseable it cannot be declared within try block, it has to be declared in the body part & has to be explicitly closed in finally block.
Is it possible for try-with-resource to fail to clean up resources unless you use the idiom incorrectly like if there are nested resources & close() call is not idempotent for the underlying resource?
What I understand is try-with-resource only ensures close() getting called behind the scene, but if close itself does not close underlying resources try-with-resource will remain ineffective to clean-up resources.
Does anyone have a contrary view or more clarification?
Yes.
try (FileSystem fs = FileSystems.getDefault()) {
return fs.getPath(aStringVar);
}
If FileSystems.getDefault() returns a sun.nio.fs.UnixFileSystem, as it did for me on a RedHat machine with Java 8 SE, it'll throw an UnsupportedOperationException while closing. Despite IntelliJ displaying warnings and telling you to wrap that in a try-with-resources, you should not, unless you want to deal with that stupid exception.
Disregarding code that does not actually work (like your example of close() methods not actually closing the resource) or such completely external factors as people attaching debuggers to side-step cleanup, I can think of three situations in which try-with-resources might fail to clean up a resource:
Power failure, hardware failure, OS crash or VM crash. There isn't much any software can do about such things, so they are outside the scope of resource handling. However, you still need to keep it in mind in case you're thinking about managing such things as mandatory locking files and whatnot with a try-with-resources statement.
Asynchronous exceptions, such as those generated by Thread.stop(). If a thread is "stopped" in this way while in the clean-up code, then the clean-up code will be aborted. The unsafety of such asynchronous exceptions is why Thread.stop() is deprecated and replaced with Thread.interrupt(), which is safe.
If System.exit() is called. This might be considered as any of the above cases, except that it might happen under "normal circumstances".
In all other respects, you should be able to rest assured that close() will be called. Try-with-several-resources is the same as nested try blocks, so clean-up code throwing exceptions won't stop other clean-up routines.

Clean up code in finalize() or finally()?

I had the general view that clean up of resources is done in the finally block,
recently I found this particular code snippet in a class and it was overriding the Object class' finalize() method.
protected void finalize() {
try {
In.close();
Out.close();
socket.close();
}
catch (Exception e) {
//logger code here
}
}
Is this a good idea? What are the pros and cons of finalize() over finally?
The finally block is just a block of code that always executes after a try block, even if there is an exception. i.e. it is local in scope
The finalize() method is an approach for cleaning up the whole object when it is garbage collected.
Java documentation of finalize()
finally solves the problem of cleaning up resources in a block of code regardless of whether an exceptional condition occurs...
finalize() is a way to clean up resources when your object is no longer being used, once the Garbage Collecter determines there are no more references to that object.
In short, to answer your question, for example, if the sockets you are closing are members of an object you should close them in the finalize() method, (although that's sub-optimal, and just for example, because there is no guarantee when the GC will actually perform the action)
If however you're opening the socket in a method, and are done with it when the method ends you should free the resources in the finally block.
Always clean up things in finally.
Cleaning up in finalize is not guaranteed to occur.
However, it is often found to clean up such things in finalizers as a last-ditch safety valve should a finally block throw another exception on you.
The real problem with relying on finalizers is something else may need the resource before the GC gets around to calling the finalizer.
Phantom References will do what you want.
Just don't use finalize. There are a few edge cases where it may be helpful (printing debug info when a class is GC'd has come in handy), but in general don't. There is nothing in the JVM contract that even says it ever has to be called.
There is a very under-publicized type of object called "References". One is made explicitly for things that you think you would use finalize for.
"Phantom reference objects, which are enqueued after the collector determines that their referents may otherwise be reclaimed."
It just occurred to me that there MUST be a description of this on the web--so I'll replace all the "how-to" stuff I just wrote with this reference.
They're not related. This is like asking, "Should you create objects in an initializer or in normal methods?" Like, it depends on what you're doing with the objects. A finalizer cleans up an object's state while it's destroyed (maybe — it's not something you should rely on), while a finally block executes code after a try block. There isn't any common situation where you'd be able to choose one or the other since they do different things.
Finalize is probably a bad idea if your application causes lots of these objects to be created. This is because finalize will cause a bottleneck as the objects become eligible for garbage collection.
There are times when finalize is the only solution; but use finally whenever you can
Finally. Finalize is bad in that it may never get called. Use finalize only as a safety net. For example an InputStream should have a finalize that closes the stream incase the applcicationforgets to. However the application should close it.
If it were me I would do the cleanup in the finalizer as well and log the cases when the cleanup was performed and then track down in the application the code that forgot to properly clean up.
There are a number of problems with the code in the question, including:
The big problem: It looks like you are trying to close a socket. Even if you don't close it properly, it will close in its own finaliser. Adding another finaliser doesn't make it any more closed.
An exception thrown by the first close will prevent the others from executing (as it happens, this doesn't matter in this example because of the peculiar behaviour of Socket).
If you do override finalize, leave it throwing Throwable (and add #Override). Technically you should also call the super in a finally block.
The Java Memory Model is mighty strange when it comes to finalisers (previous execution of code does not necessarily happen-before the execution of the finaliser). I would explain the problem, but what you need to know is that you need to stay away from finalisers.
So: Always use finally for these things. finalize is extremely specialised (and PhantomReference are probably better is superficially more complicated).
If you are looking for alternatives to finalize() the proper question would be:
Why use an explicit close() method like, for example, all the stream and writer/reader classes in java.io.* and many others - when there is finalize()?
The other answers make it clear that the disadvantage of finalize() is that you have no way to force it to run, and neither do any who might use your code.
Of course, calling a close() methode (best done in a finally block or in a close() method itself) has to be documented by the author and then remembered to be called by the ones using the code. But there are lots of examples (not only java.io.*) where this is imposed and it works.
BTW: close() is merely a convention.
Joshua Bloch makes a very clear recommendation in his book Effective Java (2nd Edition). Copied from chapter 2 Item 7: Avoid finalizers:
Finalizers are unpredictable, often dangerous, and generally unnecessary. Their use can cause erratic behavior, poor performance, and portability problems. Finalizers have a few valid uses, which we’ll cover later in this item, but as a rule of thumb, you should avoid finalizers.
Please read the reference to find out why.

Categories