This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 101221 - Thread objects leaked by profiler
Summary: Thread objects leaked by profiler
Status: VERIFIED DUPLICATE of bug 95020
Alias: None
Product: profiler
Classification: Unclassified
Component: Base (show other bugs)
Version: 5.x
Hardware: All All
: P2 blocker (vote)
Assignee: issues@profiler
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-04-16 21:12 UTC by petesoper
Modified: 2007-09-25 18:19 UTC (History)
0 users

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description petesoper 2007-04-16 21:12:50 UTC
The Profiler is treating instances of Thread and its subclasses in a special way
such that they never get finalized or collected. Sun Change Request # 6520834
was filed to document this problem (thinking it was a bug in the JDK). The
following sections are "cut and paste" from the description, comment, and
evaluation notes of the above change request.

-------
------- Sun CR 6520834 Description notes
-------

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
Microsoft Windows XP [Version 5.1.2600]

A DESCRIPTION OF THE PROBLEM :
After a thread stops, the Thread object 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 snap 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.
*** (#1 of 1): 2007-02-02 13:42:18 EST xxxx,xxxx@sun.com

-------
------- CR 6520834 Comments notes
-------

he original incident is at
http://webbugs.sfbay.sun.com/rt/incidentDisplay?incidentID=865192

(The submitter's email address is in the above incident)

****************************************************************
Update from the customer 
****************************************************************
INFO  2006-12-06 10:16:54,657 [Thread-66354 AggressivePoller
10.1.52.250] DiscoveryListener - polling 10.1.52.137 59
java.lang.OutOfMemoryError
java.lang.OutOfMemoryError
java.lang.OutOfMemoryError
INFO  2006-12-06 10:17:05,149 [Thread-66354 AggressivePoller
10.1.52.250] DiscoveryListener - polling 10.1.52.137 58
java.lang.OutOfMemoryError
WARN  2006-12-06 10:17:05,154 [Thread-331 Reader Controller
RRUTTAN-PERF] MemoryAlert - Memory Low: aggressively freeing space.
ERROR 2006-12-06 10:17:05,741 [Thread-66425 connectLater Controller
SWT-LESLIE620] SynchronousRequest -  Timed out waiting 20000 ms for
Controller SWT-LESLIE620 - /Server[@type="eventTemplates"]
WARN  2006-12-06 10:17:06,329 [Thread-331 Reader Controller
RRUTTAN-PERF] MemoryAlert - wasFree = 712, isFree = 287792, lowMark =
65536, total = 302841856
ERROR 2006-12-06 10:17:06,329 [Thread-66425 connectLater Controller
SWT-LESLIE620] Service - Controller SWT-LESLIE620 Request eventTemplates
failed: Synchronous Response timed out
WARN  2006-12-06 10:17:06,913 [Thread-331 Reader Controller
RRUTTAN-PERF] MemoryAlert - wasFree = 287792, isFree = 294312, lowMark =
65536, total = 302841856
WARN  2006-12-06 10:17:07,498 [Thread-331 Reader Controller
RRUTTAN-PERF] MemoryAlert - wasFree = 294312, isFree = 268696, lowMark =
65536, total = 302841856
java.lang.OutOfMemoryError
java.lang.OutOfMemoryError
java.lang.OutOfMemoryError
java.lang.OutOfMemoryError
WARN  2006-12-06 10:17:13,334 [Thread-48724 Reader Controller SWT-MUSIC]
MemoryAlert - Memory Low: aggressively freeing space.
WARN  2006-12-06 10:17:13,917 [Thread-48724 Reader Controller SWT-MUSIC]
MemoryAlert - wasFree = 45432, isFree = 54768, lowMark = 65536, total =
302841856
WARN  2006-12-06 10:17:14,488 [Thread-48724 Reader Controller SWT-MUSIC]
MemoryAlert - wasFree = 54768, isFree = 19936, lowMark = 65536, total =
302841856
WARN  2006-12-06 10:17:14,489 [Thread-23 Reader Controller CX20715]
MemoryAlert - Memory Low: aggressively freeing space.
java.lang.OutOfMemoryError
****************************************************************



2007-02-02 11:38:27.531  xxxx.xxxx@Sun.COM
*** (#1 of 4): 2007-02-02 13:42:18 EST nelson.dcosta@sun.com

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.
*** (#2 of 4): 2007-02-04 18:16:48 EST xxxx,xxxx@sun.com

Customer has discussed this on the forums -
http://forum.java.sun.com/thread.jspa?forumID=32&threadID=5117436
*** (#3 of 4): 2007-02-05 03:00:20 EST xxxx.xxxx@sun.com

There is nothing in the forum thread to add to this. I still suspect two
different issues.
*** (#4 of 4): 2007-02-05 04:55:34 EST xxxx,xxxx@sun.com

---------
--------- CR 6520834 evaluation notes
---------

Note from xxxx.xxxx@sun.com:

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.
*** (#1 of 2): 2007-02-05 17:50:54 EST xxxx,xxxx@sun.com

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 finalization 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.
*** (#2 of 2): 2007-04-16 16:06:28 EDT xxxx.xxxx@sun.com (java.lang IE)

--------
-------- End of Sun CR
--------

I'm judging this issue to have a high priority as more and more applications are
likely to spawn large numbers of threads, making it likely that this defect will
impact many users of the Profiler and there is no sensible workaround.
Comment 1 Jiri Sedlacek 2007-04-16 21:20:29 UTC
A known problem, already fixed in Profiler 5.5.1 RC, see Issue 95020.

*** This issue has been marked as a duplicate of 95020 ***
Comment 2 Alexander Kouznetsov 2007-09-25 18:19:24 UTC
Verified duplicate