JDK-6818960 : ImageFetcher ( MediaTracker) Thread leak
  • Type: Bug
  • Component: client-libs
  • Sub-Component: 2d
  • Affected Version: 6,7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2009-03-18
  • Updated: 2011-05-18
  • Resolved: 2011-05-18
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b132Fixed
Related Reports
Duplicate :  
Description
#1

---------- ImageFetcher Thread pool
The issue is with ImageFetcher (as used by MediaTracker). A small pool
of Threads is used, as you know, and they are allocated as needed to load Images.

In our customer's busy system, occasionally a Thread cannot be started.
This is due to an underlying OS error condition. Examples would be out
of memory for stack (if native threading), or too many threads (on a
fixed-thread-pool OS).

In the customer's system, this is a normal, if not frequent, occurrence,
and they periodically recover/reclaim resources in order to allow Java
to use more Threads. The VM is running 24/7 with a highly variable load.

Application code which fails for this reason can be unloaded and restarted.

AWT can never be restarted, so resource leaks are a problem. We have
just fixed one in ImageFetcher, as follows (example from PBP 1.1, but
similar applies to all versions of AWT):

Instead of
   info.fetchers[i] = new ImageFetcher(fetcherGroup, i);
   info.fetchers[i].start();
   info.numFetchers++;
we now do
   Thread newF = new ImageFetcher(fetcherGroup, i);
   newF.start();
   info.fetchers[i] = newF;
   info.numFetchers++;

This arranges that when start() throws an exception, the slot in the
small pool of Threads is not filled with a useless Object.



#2
----------- MediaTracker hang
In a similar vein, we have noted (but not yet fixed) that the Image for
which the ImageFetcher Threads were being started has already been
queued by the above point.

So if a new ImageFetcher Thread cannot be started, and no others are
currently running, MediaTracker will hang indefinitely waiting for this
Image to load.
We reckon it should probably report an ERROR instead.

------- 
#3 Reprodcibility
 

we reproduced the issue in-house by modifying our
implementation of Thread.start() to look at the name and detect "Image
Fetcher". We then spoofed occasional failures specifically of starting
those Threads (throwing an Error).

The extra challenge is to find a test application which has intermittent
bursts of Image loading, but I guess any interactive Image browser PBP
app would do. Or it should not be too hard to construct one for the
purpose.

[[We used the customer's Java TV stack, but that is not available to you.]]
********************

Comments
EVALUATION The root of this problem is that image fetcher code is not ready to thread starting failure. However, this seems to be possible on systems with hight load. This change can be divided in two parts: #1 avoid populating fetcher's pool with threads which couldn't start (as it was suggested by problem reporter). #2 provide a way to report image processing failure if there are no available threads to process image fetching. I suggest to change signature of the ImageFetcher.add() method and introduce a boolean return value in order to indicate whether add() operation was successful. This operation may fail if corresponding fetcher's pool is empty and attempt to create new fetcher failed (the numFetcher remains zero after createFetchers() call). If the pool is not empty, we report success even if no new fetcher have been created: all waiting images will be processed by existing fetchers.
27-03-2009

SUGGESTED FIX From Decsription: this is one suggested improvement to ImageFetcher from customer, this has not yet been validated by Sun ******* Instead of info.fetchers[i] = new ImageFetcher(fetcherGroup, i); info.fetchers[i].start(); info.numFetchers++; we now do Thread newF = new ImageFetcher(fetcherGroup, i); newF.start(); info.fetchers[i] = newF; info.numFetchers++; *********
18-03-2009