In short: I have a thread which is finished running, but not garbage collected.
In long: See following example code:
public void saveSomething() {
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
// heavy memory access (~400 MB), finishes after ~10sec
}
});
thread.start();
}
Okay, so this thread gets started and finished after some time. During this time a lot memory is used, which is okay. But my problem is:
After the thread finished, the memory is not set free
And I don't know how I can ensure that. Finished threads, which are not used anymore, should get garbage collected as far as I'm informed; but this doesn't seem to happen here :(
See this screenshot from jvisualVM:
1: I trigger the thread start by calling saveSomething()
2: Thread was finished long ago (I saw it by debugging), and I pressed "Perform GC" in jvisualvm
As you can see, after I force the GC, everything is working like I want. But this has to happen automatically. How can I do that, what am I doing wrong?
If you need more infos, please ask. Note: It seems that after a day (hopefully shorter) the memory is back to normal, maybe the GC is just "slow" or rather not very frequently timed?
What happens to the thread when garbage collection kicks off? Explanation: The thread is paused when garbage collection runs which slows the application performance. 8.
The Thread is not garbage collected because there are references to the threads that you cannot see. For example, there are references in the runtime system. When the Thread is created it is added to the current thread group.
One of the most misunderstood parts of garbage collection is that it doesn't actually collect dead or unused objects; it collects used ones, the so-called survivors. Garbage collection is slow if most objects survive the collection process.
Could it be that you are asking the wrong question? What I mean: is the fact that garbage collection is not happening "immediately" a problem for you?
I am pretty sure - when you start another such thread that needs a lot of memory, the GC will kick in all by itself.
If that "delay" is actually a problem for you, you might consider doing the "very deep dive" in order to understand how GC actually works for your version of the JVM; to then start using the many many command line options that exist to fine-tune GC behavior to your needs.
But if a "delay" in freeing up memory (to other Java objects) is not an issue; then don't start fixing it.
Garbage collection doesn't happen as soon as the thread is finished. Garbage collection will happen when it happens. The fact that when you force garbage collection via visualvm, the thread and its resources are collected correctly implies everything is ok. If you wait long enough or do more things which consume the heap then eventually your thread will be GCed.
EDIT The only caveat to this is that a running thread, even with no references, will not be garbage collected.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With