I'm starting my thread like so:
(new MyThread()).start();
I'm not keeping a reference to it anywhere, so I'm wondering if it's a safe approach - can't GC collect it since it's not referenced?
If not (I think so), then why?
If you look at the OpenJDK Java 7 source code of Thread, you'll notice that start() contains the following
group.add(this);
where group is the Thread's ThreadGroup which is managed by the JVM. So there is always a reachable reference to the Thread while it is still running. It won't be garbage collected
If this alone isn't convincing, consider that starting a new thread means creating a new call stack where the root call is one of Thread's methods, probably some native method. You can't be executing the method of an object if the object is garbage collected. As such, the Thread object must still be alive.
Related
I have a Java class which needs a monitor running parallel when instantiated. I want to keep running this monitor until the instance is not running any more or it is not referenced.
Usually I tend to use a active flag as a variable, which is closed when the class is shutdown/closed, however this has to be managed carefully and it has to be called when closing.
I am also aware of the finalize member of Object but as I remember it is not safe to use it or is it for this purpose?
Additionally a monitor might have circular references to the monitored object of course, but this might be an other issue.
You could like the object to be monitored in the thread using a WeakReference. This allows the garbage collector to collect and destroy the object.
In the thread you would have to check each time if the referenced object still exists every time you perform your checks. If it no longer exists you can safely exit the thread.
As the garbage collector does not immediately destroy objects there may be an unknown time span where the tread is still active but the monitored object is no longer used.
Say I have an object "MyObj" that runs a repeated thread and I place this object within a hash-map.
If I then remove the entry for that object, will this kill the thread? Or do I need to kill the thread before removing the object?
Removing an object from a HashMap will do nothing to the thread, and it will continue to run unless you explicitly stop it.
From Java Memory Management
Active Java threads are always considered live objects and are therefore GC roots. This is especially important for thread local variables
An object must be unreachable and have no GC roots to be considered for GC'ing.
I am considering extending java.util.Timer, and completely overriding all public methods, to use a different implementation. The one "problem" I see is, that Timer instantiate and starts a Thread in it's constructor, which I cannot use, due to it being "private". So I would like to not waste the "resources" used up by that Thread. I see at least one things I could do, which is to call super.cancel() directly in the sub-class constructor, thereby immediately closing the thread.
My question is: When are the "resources" of a java.lang.Thread allocated and released?
Allocation: At instance instantiation, or at call of start()?
Release: At "end of run()" or at instance GC time?
If it's JVM implementation specific, I'd like to know how the Oracle JVM does it?
Generally, when you instantiate an object you allocate space in memory for it. This is the case when you create a Thread object as well. It is making perfect sense, as you might wonder how can you use an object which is not stored in the memory. A Thread object does not use a lot of memory though. On the other hand, when you call the start() method the run() method of the Runnable is called and all the resources associated to the Thread will be allocated there. If the Thread is no longer running, then all the otherwise unreferenced resources used by the Thread will be de-allocated by the garbage collector eventually. So, if you ask me I think your approach to stop the Thread is good, this way only the Thread object will remain in the memory along with any other resources you reference.
I have a class (class A for example) implements Runnable. In run method I have a try catch.I want to start a new thread in catch like this
new Thread(new A()).start();
Is this a true manner to handle exceptions?
I mean maybe its a dangerous way because the heap will get full very soon; in other words garbage collector will not garbage this object because another object has been just created in it.
I mean maybe its a dangerous way because the heap will get full very soon; in other words garbage collector will not garbage this object because another object has been just created in it.
It is not dangerous for that reason. If we assume that new Thread(new A()).start(); is the last thing that the original thread does before it exits, then by the time we need to GC the original thread will have exited, and hence its stack contents won't be reachable. The only thread that will still be reachable will be the one that it still alive.
However, it is dangerous if the new thread is liable to repeat the computation and then throw the same exception again, and again, and again ... So if you do write code like this, it is a good idea for the application to keep a track of how often the thread is being re-launched, and pull the plug if it happens too often.
The other problem with the code as written is that the code that launched the original thread sees it die, but doesn't hear about the new thread. That is problematic if your want to initiate shutdown by interrupting the worker threads.
If you put those two problems (and others) together, it is better for the code that launched the original thread to be responsible for relaunching.
Thread is new parallel light weight process. As soon as its run method completed it will be eligible for GC. I don't think it effects GC life cycle of the object from where it started.
Only one new thing in your case is, handling exceptions with thread. Without knowing more details about why you want this, its hard to tell is it safe/good practice.
This is not a very good way of handling exceptions within a thread. Why would the newly created thread of the same type not have the same exception?
What you should do is have some form of thread manager up a level from the thread that will monitor for, handle, and if necessary recreate new threads when old ones fail.
This will allow you to add more ways to handle the error, and will look a lot neater if you try and debug the threads. instead of having all these hanging threads (cause the parent was cleaned by GC) you'll know all threads have spawned from the same location.
What you are proposing will not clutter the heap because threads will be GC'd when they have finished running.
If you didn't store any references to the thread that you'd created - it will be cleaned by GC when terminated. In your case I think it's pretty safe to start a new thread inside run() method.
Just be sure you are not creating inner classes or storing this thread instance - it can cause memory leak, of course.
Good luck
I'm writing a chat server in Java. I was using a fixed array of runnable classes where each element in array represents a client. The threads created are in an infinite loop which reads from socket stream.
Now I want to do it with a list so I don't have to worry about array size and it sounds more legit way of doing it. However I couldn't be sure if removing an item also terminates the thread. Actually I have no idea what it does. Also, I'm wondering is there any other possible issues with using list in that kind of situaton. Finally, how about array of Timer? Since I've used Timer for each client, again, does removing a Timer from a Timer list also stops its schedule? Any possible problems?
An object exists in itself - storing a reference to that object in a list does not change its behaviour.
So if you have a Runnable task which is running in a thread, adding it to / removing it from a list does not make a difference to that Runnable and the thread will continue running it.
The same applies to a Timer and any other objects.
Side note: there is one situation where removing an object from a list can make a difference: it is if that object is only reachable through that list. After being removed, because it is not reachable any longer, it becomes eligible for garbage collection. But that does not apply to a running thread or active timer.
You have a thread object. A reference to it was inserted into an array. Adding or removing the reference from the array (i.e. the thread) is not going to cause any unknown side effects, so you are good. If you want to stop the thread you will have to implement that either internally in your run method. Garbage collection is not an issue here.
Timer's the same issue again: they are all object references.
A running thread is considered a so called garbage collection root. Anything that is a root or can be (indirectly) referenced from the root will not be garbage collected. When the garbage collector determines whether your object is 'reachable' or not, it is always doing so using the set of garbage collector roots as reference points.
Hey there i will refer to this question!
If the thread is started it will not garbage collected as it is referenced by the containing thread.
It will garbage collected if it is done or not started yet!
The reason for this is, when started the thread-object gets added to the current ThreadGroup (a bit more complex under the hood :) ) and when its done it will automatically removed.