Garbage Collector doesn't immediately collect finished thread [duplicate] Garbage Collector doesn't immediately collect finished thread [duplicate] multithreading multithreading

Garbage Collector doesn't immediately collect finished thread [duplicate]


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.

EDITThe only caveat to this is that a running thread, even with no references, will not be garbage collected.


I agree with the previous answers. This program demonstrates the fact that the "problem" is not specific to thread creation. In general, gc is done when needed or when specifically requested.

public class Test {  public static long memInUse(){    Runtime r = Runtime.getRuntime();    return r.totalMemory()-r.freeMemory();  }  public static void main(String[] args){    System.out.println("Initial memory: "+memInUse());    long[] bigArray = new long[1000000];    System.out.println("Memory after array allocation: "+memInUse());    long endTime = System.currentTimeMillis()+10000;    while(System.currentTimeMillis() < endTime){      System.out.println("While array exists: "+memInUse());      try{        Thread.sleep(1000);      }catch(InterruptedException e){        // Deliberately ignore the exception.      }    }    bigArray = null;    System.out.println("After null assignment: "+memInUse());    endTime = System.currentTimeMillis()+10000;    while(System.currentTimeMillis() < endTime){      System.out.println("While array reference null: "+memInUse());      try{        Thread.sleep(1000);      }catch(InterruptedException e){        // Deliberately ignore the exception.      }    }    System.gc();    System.out.println("After gc: "+memInUse());  }}

Output:

Initial memory: 2684536Memory after array allocation: 10684552While array exists: 10684552While array exists: 10684552While array exists: 10684552While array exists: 10684552While array exists: 10684552While array exists: 10684552While array exists: 10684552While array exists: 10684552While array exists: 10684552While array exists: 10684552After null assignment: 10684552While array reference null: 10684552While array reference null: 10684552While array reference null: 10684552While array reference null: 10684552While array reference null: 10684552While array reference null: 10684552While array reference null: 10684552While array reference null: 10684552While array reference null: 10684552While array reference null: 10684552After gc: 1622584