Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6520834
Votes 4
Synopsis (thread) Thread objects are not garbage collected
Category java:classes_lang
Reported Against
Release Fixed
State 11-Closed, Not a Defect, bug
Priority: 4-Low
Related Bugs
Submit Date 02-FEB-2007
Description
FULL PRODUCT VERSION :
C:\>java -version
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)

ADDITIONAL OS VERSION INFORMATION :
C:\>ver
 customer  Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
After a thread stops, the Thread  customer  never gets garbage collected.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1) Profile the attached source code in NetBeans 5.5.
2) Select Analyze Memory Usage
3) Select Record both Object Creation and Garbage Collection
4) Select Track Every 1 Object Allocations
5) Let the program run until you see some threads stopping
6) Invoke the gabage collector
7) Take a snapshot
8) Repeat 5 to 7 a few times

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
In the Memory  customer  shot  I would expect to see that there are less Live "Threads" objects than Allocated "Threads" objects.
ACTUAL -
There is always the same number of Live "Threads" objects as Allocated "Threads" objects.

This is clearly a memory leak defect.

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public class Threads extends Thread
{
    public Threads()
    {
    }

    public void run()
    {
        System.out.println(getName() + " - starting");
        try
        {
            sleep((int) (Math.random() * 100000));
        }
        catch (InterruptedException e)
        {
        }
        System.out.println(getName() + " -         stopping");
    }

    public static void main(String [] arguments)
    {
        for (int i = 0; i < 100; i++)
        {
            Threads threads = new Threads();
            threads.start();
            try
            {
                Thread.sleep(2000);
            }
            catch (InterruptedException e)
            {
            }
        }
        System.exit(0);
    }
}

---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
No easy workaround, if you application continuously creates threads you have a memory leak. The only potential solution would be to recycle threads before they stop, which leads to some excessively complicated coding.
Posted Date : 2007-02-02 18:42:18.0
Work Around
N/A
Evaluation
Note from   xxxxx@xxxxx  :

A simple test shows that Thread objects are not being leaked in general:

public class ThreadLeak {

    public static void main(String[] args) throws Throwable {

	final int NTHREADS = 200000;

	for (int i = 0; i < NTHREADS; i++) {
	    Thread t = new Thread() {
		    protected void finalize() {
			System.out.println("Got me!");
		    }
		};
	    t.start();
	    t.join();
	}

	System.out.println("DONE");
    }
}

I suspect there are two different things going on here:

1. In the real code something (perhaps threads) is being retained by the application and so they are running out of memory. A simple heap analysis should be able to confirm this.

2. The "test" using the supplied program and NetBeans could be encountering an issue with running under a debugger/profiler.
Posted Date : 2007-02-05 22:50:54.0

I eliminated your "thing # 1" above, as the program as submitted fails to GC the Threads objects, even when the size of each instantiation is jacked up with an instance array field holding an empty array: the Threads finalizer is never reached, even up to the point of heap exhaustion.

However the finger must be pointed to the Profiler, as running the app (with the above array and a means of detecting finalization) works fine when run by NetBeans. It's only when run with the Profiler under NetBeans that finalization and collection fail to happen. I set up a nested class had the main loop instantiate instances of that and finalizatin and GC of those objects worked fine.

So there's something about instances of Thread and it's subclasses that's special with the Profiler such that it's trapping them. 

An "Issuezilla" bug entry will be filed at the NetBeans site and the ID of that entry will be added to these notes before this CR is closed/not a defect. In searching the NetBeans bug database one "similar" bug was found, but it appears to be to do with threads NetBeans creates for some purposes, not application threads.
Posted Date : 2007-04-16 20:06:28.0

This is now NetBeans "issue # 101221" which is documented here:

     http://www.netbeans.org/issues/show_bug.cgi?id=101221
Posted Date : 2007-04-16 20:15:52.0

I didn't do the right kind of searches with NetBeans Issuezilla, or it is case sensitive, or whatever. This bug has already been reported and is fixed in NetBeans Profiler 5.5.1 RC. More details here:

   http://www.netbeans.org/issues/show_bug.cgi?id=95020
Posted Date : 2007-04-16 20:25:26.0
Comments
  
  Include a link with my name & email   

Submitted On 05-FEB-2007
Eric-the-K
See also http://forum.java.sun.com/thread.jspa?forumID=32&threadID=5117436


Submitted On 08-FEB-2007
Eric-the-K
OK, I added a finalize method to my test class and a System.gc() inside my main loop. When I run the program normally, without the profiler, everything works fine - I can see the finalizers being called.

However, when I run the program under the profiler, the finalize method on the Thread object is never called.

I guess it's time to bug the NetBeans people.



PLEASE NOTE: JDK6 is formerly known as Project Mustang