JDK-4508232 : (thread) Unborn Threads are not garbage collected
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.3.0,1.4.0
  • Priority: P5
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic,windows_2000
  • CPU: generic,x86
  • Submitted: 2001-09-27
  • Updated: 2004-02-13
  • Resolved: 2004-02-13
Related Reports
Duplicate :  
Duplicate :  
Description

Name: yyT116575			Date: 09/27/2001


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0)
Java HotSpot(TM) Client VM (build 1.3.0, mixed mode)


In our experiments with Jtella (Gnutella servent in Java) we noted that Threads
were getting lost. We were printing out "activeCount" and using "enumerate" to
list existing threads.  The numbers did not match and the discrepancy would
increase with time.... and eventually the program would run out of memory.  The
enclosed mini program illustrates the problem and We now know why it happens.

Basically, Java Threads that are not "started" are never garbage
collected. In UNIX, we speak of Zombie (walking dead) processes that are
dead but still use resources. Here in Java, we have the same thing at
the other end of the life cycle: walking unborn Threads.  We understand that
"active" Threads should not be garbage collected even if there are unreachable
from the MAIN program; however once a Thread is no longer alive (has returned
from its "run" method); it should be fair game.  The problem lies with Threads
that have been created but not "started". If the user has no reference to them;
there is no way he can "start" them so that they will terminate: they are not
yet alive but are not dead.  Looking at the source code for ThreadGroup, we
suspect that they unborn Threads have pointers in the Group Thread Table - so
that they are not garbage collected.  Because "enumerate" only returns
references to "alive" threads, we can't get at them that way.

Example:
//   AliveTest.java:   program to test theory that Threads which are not started
//                     are not garbage collected

//   - We create "T" Threads but don't "start" them.  The output shows:
//      a)  that creation is fast (compared to -starting- Threads)
//      b)  that memory is garbage collected
//      c)  the Thread ACTIVE count always increases
//      d) eventually we run out of memory

public class AliveTest {
        
  public static void main (String [] args) {
    long t1 = System.currentTimeMillis();
    Runtime r = Runtime.getRuntime();

    for (int i = 1;  ; i++) {
      // new T().start();

      new T();
      if (i%100==0) {
        System.out.println ("Threads created: " + i
            + ", t: " + (System.currentTimeMillis()-t1)/1000
            + " sec, activeCount: " + Thread.activeCount()
            + ",   Free mem:" + r.freeMemory()/1000 + " K");
      }
    }
  }

}


class T extends Thread {
  int [] a = new int [10000];
  public void run() {
    a[0] = 1;
  }
}

/* ----------------------------- Output ---------------------------

mere> java AliveTest
Threads created: 100, t: 0 sec, activeCount: 101,   Free mem:2261 K
Threads created: 200, t: 0 sec, activeCount: 201,   Free mem:2726 K
Threads created: 300, t: 0 sec, activeCount: 301,   Free mem:6120 K
Threads created: 400, t: 0 sec, activeCount: 401,   Free mem:2107 K
Threads created: 500, t: 0 sec, activeCount: 501,   Free mem:9602 K
Threads created: 600, t: 0 sec, activeCount: 601,   Free mem:5580 K
Threads created: 700, t: 0 sec, activeCount: 701,   Free mem:1567 K
Threads created: 800, t: 0 sec, activeCount: 801,   Free mem:16968 K
Threads created: 900, t: 0 sec, activeCount: 901,   Free mem:12955 K
Threads created: 1000, t: 0 sec, activeCount: 1001,   Free mem:8936 K
Threads created: 1100, t: 0 sec, activeCount: 1101,   Free mem:4914 K
Threads created: 1200, t: 0 sec, activeCount: 1201,   Free mem:895 K
Threads created: 1300, t: 1 sec, activeCount: 1301,   Free mem:13474 K
Threads created: 1400, t: 1 sec, activeCount: 1401,   Free mem:9455 K
Threads created: 1500, t: 1 sec, activeCount: 1501,   Free mem:5436 K
Threads created: 1600, t: 1 sec, activeCount: 1601,   Free mem:1422 K
Exception in thread "main" java.lang.OutOfMemoryError
	<<no stack trace available>>
---------------------------------------------------------------------- */
(Review ID: 132751) 
======================================================================