From the Java API doc:
The Java Virtual Machine continues to execute threads until following occurs:
All threads that are not daemon threads have died, either by returning from the call to the run method or by throwing an exception that propagates beyond the run method.
I hope my assumption is correct that once thread finishes its run()
method it becomes eligible for garbage collection. In the same context I am just curious to know about:
- If it doesn't become eligible for garbage collection after returning
from
run()
, should one set its reference tonull
to do that? - Being eligible for garbage collection doesn't necessarily mean that the object will be removed from memory. It is at the sole discretion of the underlying operating system / JVM when it is garbage collected. But how can one make sure (either through a Java program or external tool) that the object is completely removed from the memory?
- If a thread is said to be dead once it finishes its run() method, why
can I still be able to execute
isAlive()
orgetState()
on the same thread object? Both the calls returnfalse
andRUNNABLE
respectively.
The
Thread
class is a proxy for the real thread which is in native memory.There is actually a bit of code after run(), this code handles uncaught exceptions.
Once the thread dies its native memory and stack are freed immediately without needing a GC. However, the
Thread
object is like any other object and it lives until it is GC has decided it can be free e.g. there is no strong reference to it.Similarly, a FileOutputStream is a proxy for a file in the operating system. You can still have a reference to the object even after the file has been
close()
or even deleted.You rarely need to do this anywhere. In fact it is often simpler not keep a reference to the thread in the first place, or to use an ExecutorService to manage your threads.
When I have an object which has a
Thread
field I often have this object die when the thread dies, thus the field doesn't need to benull
ed out.I also use the built in thread pool used for Fork/Join. This is a more light weight way to perform tasks in a background thread as it doesn't create and destroy threads so much.
You can't and generally shouldn't try. The GC will clean up resources when it needs to.
The thread object is like any other object. You can call methods on it for as long as you hold a reference to it.
It seems that you are tripping on the common pitfall with unterstanding threads in Java: the thread itself is not a Java object. It is a native resource (thread of execution). It will be "removed from memory" as soon as it has finished running its code.
The instance of
Thread
, on the other hand, is just a plain Java object with the same lifecycle as any other object—except for the extra rule that it stays reachable at least as long as the underlying native thread is alive. This is implied by the fact that you can always callThread.currentThread()
.So, if you retain a reference to a
Thread
instance in charge of a dead thread, it will not magically disappear and all its methods will continue to operate as specified. You can hold on to it for as long as desired.Regarding your question 2, "removing" an object from memory is a virtually meaningless term. The runtime itself has in fact no idea about the collected objects—they are those which it has forgot about.
There are two things to consider about threads.
So my advice is to treat "dead" threads like you would treat an object of type
List
orMap
for example. What applies to them applies to threads that finished running.The fact that the thread has finished execution does not alter the validity of the reference to the object. While you hold that reference the Thread object cannot be garbage collected.
This means that while you hold a reference to the Thread you are able to call things like
isAlive
. When you release all references the Thread can be garbage collected.If you wish to have a reference to an object without preventing that object from being garbage collected then you must use a a WeakReference. When you use such a reference you must check to see if the object referenced still exists.
What I believe is garbage collector collects an object when there are no references of an object in the memory. In case of thread, the process is running so thread objects won't be collected by garbage collector.
Every object tree must have one or more root objects. As long as the application can reach those roots, the whole tree is reachable via
If it doesn't become eligible for garbage collection after returning from run(), should one set its reference to null to do that?
It is always better to explicitly set objects to null (if you are certain that they will not be used in the future) to make the GC's job little easier.
}
}
O/P : case : 1 --> if thread is running when call to gc is made.
case :2 --> IF thread has finished running when call to gc is made.
Being eligible for garbage collection doesn't necessarily mean that the object will be removed from memory. It is at the sole discretion of the underlying operating system / JVM when it is garbage collected. But how can one make sure (either through a Java program or external tool) that the object is completely removed from the memory?
In Java, you can only say when the object becomes unreachable (not GCed, unreachable.).
finalize()
will be called when your onjecy becomes unreachable.If a thread is said to be dead once it finishes its run() method, why can I still be able to execute isAlive() or getState() on the same thread object? Both the calls return false and RUNNABLE respectively. - The thread might have finished its execution. But it will still be in a state. the terminated state. You are calling these methods on a thread instance. So, it still holds some state data.