I'm extremely confused about how finalizers work in the JVM regarding Garbage Collection from several sources here and around the internet.
It is my understanding, the usual approach is not to rely on finalizers to perform clean up as there's no guarantee about when they will be called or whether they would be called at all if the application finishes. However, I would still expect them to be called when the application finishes and all object cease to exist, as long as the application is alive.
In my particular case, I have an application with a class that opens a connection to another resource.
Simplified we will have
public class MyClass {
Connection connection = new Connection();
public MyClass() {
connection.open();
}
public void close() {
connection.close();
}
#Override
protected void finalize() {
connection.close();
}
}
public class Main {
public static void main(String[] args) {
MyClass instance = new MyClass();
// If I call instance.close(), application ends when it reaches end of main method
// instance.close()
// If not called, application will not end.
}
}
Note the encapsulation purpose of "MyClass", the calling code does not necessarily need to know (nor does it need to) that he's using a non managed resource.
What happens is the application keeps running for ever, I assume hanged up on the open connection without ever releasing it since GC isn't called (and will never be called since there's no real memory pressure).
If the GC is not called when the application finishes, is there a way to guarantee the non managed resource (the connection) is closed when the application finishes? Obviously without having to explicitly call close.
I've seen the AutoClosable interface, and that is definitively an option but it still doesn't guarantee the connection will be eventually dropped when the application finishes.
If the GC is not called when the application finishes, is there a way to guarantee the non managed resource (the connection) is closed when the application finishes? Obviously without having to explicitly call close.
If you call (on Unix)
kill -9 {pid}
the process dies immediately without notifying the process. e.g no finally blocks are called. There is nothing you can do to prevent this.
You can enable to that finalizers are called on a graceful shutdown with runFinalizersOnExit but only on a graceful shutdown.
BTW If you pull out the power, or the network connection you won't have a graceful disconnect either, so you can't avoid needing to handle this, all you can do is cleanup on a graceful close()/shutdown.
Related
Im writing an SDK that has a singleton class with ExecutorService. It looks something like this:
public class MySingleton {
private static MySingleton mInstance;
private ExecutorService mExecutorService;
private MySingleton() {
mExecutorService = Executors.newSingleThreadExecutor();
}
// ...
public void doSomething(Runnable runnable) {
mExecutorService.execute(runnable);
}
}
This SDK class is intended to be used throughout the application to run tasks/Runnables, and doSomething() function is to queue and run all Runnables in a single thread.
But one thing I couldn't figure out is when to call the ExecutorService.shutdown() method. If I call it like so:
public void doSomething(Runnable runnable) {
if (mExecutorService.isTerminated()) {
mExecutorService = Executors.newSingleThreadExecutor();
}
mExecutorService.execute(runnable);
mExecutorService.shutdown();
}
It would defeat the purpose of using one Thread because if the old Runnable is still running when doSomething() is called the 2nd time, there may be two different Threads running simultaneously. Of course I can have a function that manually shuts down the ExecutorService, but requiring the user of the SDK to explicitly call the shutdown function didn't seem appropriate.
Can anyone show me some tips on when/how to call ExecutorService.shutdown() in an Android application? Thanks
There is no good reason to call shutdown each time you execute some task. You might want to call shutdown when some part of your application is being closed/finished. Ie. when Service is being stopped - then if it used executors - then I suppose you should shutdown them - but actually the point is to allow all the tasks to finish before the service quit logic will perform some finishing code. ie. by using:
executors.shutdown();
if (!executors.awaitTermination(5, TimeUnit.SECONDS)) {
executors.shutdownNow();
}
as an example, such service could be used to download some files, user would ie. want to pause downloading - ie. by opening camera application (that might stop your application/service to reclaim its resources/memory).
In an Android application, there is no need to shutdown a singleton ExecutorService unless it has any idle thread. According to Android docs:
A pool that is no longer referenced in a program AND has no remaining
threads will be shutdown automatically. If you would like to ensure
that unreferenced pools are reclaimed even if users forget to call
shutdown(), then you must arrange that unused threads eventually die,
by setting appropriate keep-alive times, using a lower bound of zero
core threads and/or setting allowCoreThreadTimeOut(boolean).
So if you use Executors.newCachedThreadPool() or create a ThreadPoolExecutor with corePoolSize of 0, it will automatically be shutdown when the application process dies.
I have an application with a well defined Try/Catch/Finally chain that exits and executes the finally block just fine under normal conditions, however when someone prematurely hits the red X in the GUI, the program fully exists (code = 0) and the main thread's finally block isn't called.
In fact, I do want the program to exit upon a click of the red-X, but what I do not want is a skipping of the finally{} block! I sort of put in the most important part of the finally block manually in the GUI but I really do not want to do it this way since I want the GUI decoupled from the actual program:
class GUI { // ...
...
mainFrame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent evt) {
try {
processObject.getIndicatorFileStream().close();
} catch (Exception ignore) {}
System.exit(0);
}
});
...
}
But I'd prefer to just have a call like this:
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
And make sure that all the finally{} blocks get called from each thread after the Exit.
I know this is actually expected. If the application is closed from a separate thread (say the GUI thread) then the main thread will just stop in its tracks.
In short -- how do I ensure that a System.exit(0) or a JFrame.EXIT_ON_CLOSE will still cause each thread's finally block to execute?
If you have no other design change choices then what you may need is a JVM shutdown hook, which can be added to run a piece of code when System.exit is called.
Shutdown Hooks are a special construct that allow developers to plug
in a piece of code to be executed when the JVM is shutting down. This
comes in handy in cases where we need to do special clean up
operations in case the VM is shutting down.
You can add a shutdown hook as mentioned here:
Runtime.getRuntime().addShutdownHook(Thread)
Read more about shutdown hooks here:
http://java.dzone.com/articles/know-jvm-series-2-shutdown
Word of Caution:
We must keep in mind is that it is not guaranteed that shutdown
hooks will always run. If the JVM crashes due to some internal error,
then it might crash down without having a chance to execute a single
instruction. Also, if the O/S gives a SIGKILL
(http://en.wikipedia.org/wiki/SIGKILL) signal (kill -9 in Unix/Linux)
or TerminateProcess (Windows), then the application is required to
terminate immediately without doing even waiting for any cleanup
activities. In addition to the above, it is also possible to terminate
the JVM without allowing the shutdown hooks to run by calling
Runime.halt() method.
If you happen to have such threads which can legally be stopped at any time, at any point at all within their loop, at any point within any method which they invoke, and may I warn you that it is very unlikely that you do, then you can stop all of them upon program exit. This will result in an exception being thrown in each thread, and the finally blocks will execute.
However, the proper way to achieve your goal and have GUI decoupled from the program logic, is to issue a single "exit" signal from the GUI, which will trigger all the application cleanup, which is written in an entirely different class. If you have running threads, then implement the interrupt mechanism in each of them.
There are many ways to achieve the exit signaling. For example, your business code could register a GUI listener for a special event, which would trigger the cleanup. You could also have a thread which doesn't do anything else but await on a CountDownLatch which would be countDown from the GUI.
Please, do not at any cost use a shutdown hook. This is the dirtiest mechanism imaginable, and it is there only as a last resort, when all regular cleanup procedures fail. It is never to be used as a part of the regular shutdown routine.
In summary, there is no royal way to clean application shutdown. You must implement specific mechanisms for each specific concern.
With modern Java, Window.dispose() on all application windows can offer more graceful possibility to exit an AWT application than System.exit(0), see
https://docs.oracle.com/javase/8/docs/api/java/awt/Window.html#dispose--
/** Listens and closes AWT windows.
* The class is implemented as singleton since only one is needed.
*/
public class ExitListener extends WindowAdapter {
/** the instance object */
private static final ExitListener INSTANCE = new ExitListener();
// hide the constructor
private ExitListener () {}
/** retrieve the listener object */
public static ExitListener getInstance () {
return INSTANCE;
}
#Override
public void windowClosing ( final WindowEvent e ) {
e.getWindow().dispose();
}
}
and with your windows
window.addWindowListener( ExitListener.getInstance() );
However, be careful in adverse environments, see:
https://docs.oracle.com/javase/8/docs/api/java/awt/doc-files/AWTThreadIssues.html#Autoshutdown
Does a thread self-delete and get garbage collected after it runs or does it continue to exist and consume memory even after the run() method is complete?
For example:
Class A{
public void somemethod()
{
while(true)
new ThreadClass().start();
}
public class ThreadClass extends Thread{
public ThreadClass()
{}
#Override
public void run() {......}
}
}
I want to clarify whether this thread will be automatically removed from memory, or does it need to be done explicitly.
This will happen automatically i.e. memory will be released automatically once the thread is done with its run method.
Threads only exist until the end of their run method, after that they are made eligible for garbage collection.
If you require a solution where memory is at a premium, you might want to consider an ExecutorService. This will handle the threads for you and allow you to concentrate on the logic rather than handling the threads and the memory.
Threads are automagically garbage collected on completion of the run method, hence you do not have to do it explicitly.
Threads will be garbage collected after their run method has completed. The notable exception to this is when you are using the android debugger. The android debugger will prevent garbage collection on objects that it is aware of, which includes threads that have finished running.
Why do threads leak on Android?
I have a static, periodic, java Timer/TimerTask that I would like to shutdown when the app does. I don't want the app hanging because some thread is still running (like what happens in debug mode in eclipse, some environments may kill the thing anyway). The reason I have it static is I plan to have some (very simple, probably just a counter) shared memory in all of the containing class's instances with the Timer so I feel class scope is appropriate.
My question is how best to do the shutdown of the Timer? Is this an appropriate time to use finalize? This timer seems benign enough that having a non-deterministic call to finalize may work? Would probably need to do some kind of instance counting to verify that there are no longer any instances of the class out there? Suggestions on ways to manage the shutdown of the static Timer are welcome.
pseudo code:
class foo {
private static Timer someTimer = null;
public foo() {
if(someTimer == null) {
someTimer = new Timer(new TimerTask(...));
}
}
//how should I shut this thing down?
protected void finalize() throws Throwable {
}
//or is better to have shutdown() called explicitly?
}
It all depends on what your app actually does, but in general there will be some kind of event to signal that the app is being shutdown. For example if it's a GUI app, then maybe this will be the "user clicked on the Quit button" event. Or it's a webapp based on the servlet API, it will be an event fired by a ServletContextListener.
You should add a listener for this event, which calls some kind of shutdown method on your foo object. Inside this shutdown method the foo should take care of cleaning up its resources, including stopping the timer.
As a last resort, you might want to investigate JVM shutdown hooks
I see that all the stop and destroy and anything else that deals with cleanup methods have been deprecated.
If I have a new Thread() or a class that extends Thread running, do I need to do anything in its run() method other than let it get to the end of regular execution? Or is there a background mechanism that understands that the Thread has run through all its tasks and can be destroyed?
When you call start() on your thread, native mechanism in JVM close to the operating system are starting your thread, eventually executing run(). When run() finishes, JVM takes care of everything.
You might be concerned about garbage collection or other resources cleanup. Of course if you open file/network connection inside a thread, it must be closed like everywhere else. Also the garbage collector, while analyzing live objects, takes into account objects referred from running threads. But the moment thread finishes, all the objects referenced by it (or by Runnable implementation passed to the thread) are eligible for garbage collection.
quick&dirty edit for exit method of Thread, as visible contextClassLoader is missing x.x
private void exit() {
if (group != null) {
group.remove(this);
group = null;
}
/* Aggressively null out all reference fields: see bug 4006245 */
target = null;
/* Speed the release of some of these resources */
threadLocals = null;
inheritableThreadLocals = null;
inheritedAccessControlContext = null;
blocker = null;
uncaughtExceptionHandler = null;
}
No cleanup needed. Once it finishes its task, the jvm will kill it.
The stop() method actually causes the Thread to throw an Error or Exception. The reason it is deprecated is this can happen anywhere in the code anything it modifies in a potentially unknown state. stop() is only really safe when stopping the current thread because you know when it will happen. BTW, You can catch the Error/Exception which would mean the Thread does not stop().
In any case, the result is the same, the run() returns (or fails to catch an Exception/Error). The stop() method triggers a special Error called ThreadDeath. The only thing special about it is that normally, an uncaught exception/error is printed, but this one is not. (And it doesn't have Error at the end of its name ;) You can change this behaviour if you wish.
When the Thread is no longer referenced, it can be cleaned up. (just like any other object) Note: you can hold a reference to it in another thread, preventing it from being cleaned up even thought it has finished.