JDK-4902813 : (thread) Thread is not garbage collected if it is not started
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: windows_2000
  • CPU: x86
  • Submitted: 2003-08-07
  • Updated: 2003-08-07
  • Resolved: 2003-08-07
Related Reports
Duplicate :  
Description

Name: rmT116609			Date: 08/07/2003


FULL PRODUCT VERSION :
java version "1.4.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-b92)
Java HotSpot(TM) Client VM (build 1.4.0-b92, mixed mode)

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


FULL OPERATING SYSTEM VERSION :
Windows - all versions

A DESCRIPTION OF THE PROBLEM :
The code below causes OutOfMemory, because MyThread
instances are not garbage-collected:


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Run the code below

ERROR MESSAGES/STACK TRACES THAT OCCUR :
OutOfMemory error

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class ThreadTest {
  class MyThread extends Thread {
    byte[] array = new byte[1024*1024]; // 1 MB
  }
  public void run() {
      int i = 0;
      while (true) {
          new MyThread();
          System.out.println("Thread " + ++i + " created.");
      }
  }
  public static void main(String[] args) {
    ThreadTest threadTest1 = new ThreadTest();
    threadTest1.run();
  }
}
---------- END SOURCE ----------

The problem still exists in 1.4.2. Here is the output of java -version:
java version "1.4.2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2-b28)
Java HotSpot(TM) Client VM (build 1.4.2-b28, mixed mode)

The output of sample code I posted is:
Thread 1 created.
Thread 2 created.
...
Thread 60 created.
Thread 61 created.
Thread 62 created.
Exception in thread "main" java.lang.OutOfMemoryError
(Of course it depends on the heap size specified)

This bug exists since v1.2. I decided to check the source code of the Thread class and found the
following:

    public Thread(Runnable target) {
	init(null, target, "Thread-" + nextThreadNum());
    }

the init() method calls ThreadGroup.add(this). And as you can see - this
method creates a new reference to the thread - adding it to an array.

   void add(Thread t) {
	synchronized (this) {
	    if (destroyed) {
		throw new IllegalThreadStateException();
	    }
	    if (threads == null) {
		threads = new Thread[4];
	    } else if (nthreads == threads.length) {
		Thread newthreads[] = new Thread[nthreads * 2];
		System.arraycopy(threads, 0, newthreads, 0, nthreads);
		threads = newthreads;
	    }
	    threads[nthreads] = t;

	    // This is done last so it doesn't matter in case the
	    // thread is killed
	    nthreads++;
	}
    }

this reference is removed only by the ThreadGroup's method remove(Thread),
but I can't find where it is called - probably from the native code.

CUSTOMER WORKAROUND :
start the thread or use Runnable instead of extending Thread
(Incident Review ID: 167041) 
======================================================================

Comments
EVALUATION Possibly a duplicate of 4521146. -- iag@sfbay 2003-08-07
07-08-2003