Question

[Before I begin I tried searching related questions, since I found none, I ask a question here]

I am learning Java, and the following scenario hit my head:

class MyThread extends Thread {
    void run(){
        //a heavy function
    }
}

And now in the main thread, I invoke this thread as:

public static void main(...){
    new MyThread().start();
    System.gc(); //just a request..
    //end of main thread too.
    //Reference to that MyThread object is now zero.
}

I ran that code. It seems the thread is still alive. The program ends when all the threads quit.

My questions:

  • When the reference count is zero, wont the thread be eligible for GC? If it is really eligible, what is the behaviour of garbage collection? Will the thread be terminated?
  • I know its a bad thing to do but is it well defined to not have otherThread.join() in main()?

I have a few explanation of myself (but I do not know how right I am -- the reason I made a post here):

  • JVM maitains a reference to the thread as long as it is active. So ref count is never really zero.
  • The executing function has an implicit this reference, so the ref count is again not zero.

Am I correct in any of the explanations above? Or is there any other explanation altogether?

Thanks and regards :)

Was it helpful?

Solution

Each running thread constitutes a root for the GC. Any object reachable from one of the roots is not eligible for GC, and the thread has a thread-local reference to the java.lang.Thread instance (returned by Thread.currentThread()). So no, your thread won't be GCed until it ends running, since the Thread instance is reachable from the running thread.

I don't see why it would be a bad thing not to call join() on the spawned thread. If you don't care when the spawned thread ends, you don't need to join it. The application will stop when the last non-daemon thread stops running.

Also, note that the number of references is not what is used by the GC to tell if an object is eligible for GC or not. Graphs of objects which maintain references to each other (a DOM tree for example) can be eligible for GC, if the graph is not reachable anymore.

OTHER TIPS

1. JVM will terminate only when all the Non-Daemon thread including the Main thread has terminated. (Main thread not the main() method).

2. A Thread will die immediately as it has finished running its run() method, But as you will be knowing that, every thread (toe, ie thread of execution) is associated with the Instance of the Thread class.

3. So when the thread die, it moves in to the dead state (i am not mentioning the thread pool here) , But the object of Thread class which was associated with the thread is still there, but has permanently lost its threadness.

4. But there is a high chance that your thread is still running only the main method has finished.

5. Calling join() is not at all bad, but should be used with caution.

When the reference count is zero, wont the thread be eligible for GC?

No. A thread becomes eligible for GC when it terminates and there are no references.

If it is really eligible, what is the behaviour of garbage collection? Will the thread be terminated?

See above.

I know its a bad thing to do but is it well defined to not have otherThread.join() in main()?

It isn't a bad thing to do, and it is perfectly well-defined: the JVM will exit when all the non-daemon threads have exited.

JVM maitains a reference to the thread as long as it is active. So ref count is never really zero.

Correct.

The executing function has an implicit this reference, so the ref count is again not zero.

Incorrect. Consider static methods. The executing function is executing in an active thread, by definition, so the thread is active, by definition, so it can't be GC'd. Your thinking here is rather circular.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top