JDK-4525843 : RAS: (swing) should attempt to reduce or eliminate use of finalizers
  • Type: Bug
  • Component: client-libs
  • Sub-Component: javax.swing
  • Affected Version: 1.3.0,1.4.0,1.4.1
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_2000
  • CPU: generic,x86
  • Submitted: 2001-11-11
  • Updated: 2003-04-12
  • Resolved: 2002-08-12
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.
1.4.2 mantisFixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
A recent failure of the AWT Reliability test appeared to be 
caused by allocation outpacing the Garbage Collector.  
Peter Kessler expressed the opinion that it was likely to be  
the Finalizer that was being overwhelmed (see below for 
his email on the subject).  He also explained why finalization 
is such a drain on resources, inhibits scalability, etc., and 
expressed the opinion that finalizers could often be replaced 
by more efficient methods:  

> There are lots of good ideas floating around about how to get
> the "clean up" aspects of finalization without its drawbacks.
> Mostly they involve moving to weak or phantom references, or
> reducing what's accessible from any remaining final references.
> Maybe we should make up a "best practices" document based on
> examples we fix from the AWT/Swing code.
>                         ... peter

We should investigate the possibility of removing or decreasing 
our dependence on finalizers in the Tiger time frame, or earlier.  
Toward that end, I have filed bugs against AWT, Drag&Drop, 2D, 
Swing, and Input Methods as placeholders.  

- Eric 

--------- Begin email from Peter Kessler -------------------------

Remember, every object with a finalize method has to be discovered 
to be otherwise unreachable once to put it on the finalizer queue, 
then its finalize() method has to be run, then it has to be 
discovered to be unreachable again before the storage for it 
can be reused.

If your application uses 100% of the CPU cycles available, 
the finalizer thread may fall behind.  If the finalizer thread 
falls behind, objects remain in the heap for too long, and the 
heap expands to accomodate them (up to your maximum heap size), 
but full collections slow down because the heap is bigger and 
the collector has to look at more objects.  (See my JavaOne 
demo for details.)

If the problem goes away when you add small amounts of idle time 
to your application, then the finalizer queue is probably the 
problem, as the "idle" time is used to run the finalizer thread.  

(We need better debugging hooks to let users see the length (and 
volume) of the finalizer queue.  The finalizer queue is in the 
libraries, not the VM.  From the VM I could find the finalizer 
queue and run down it to find its length, but that's always seemed 
like the wrong hammer to use.  Adding a counter to Finalizer.java 
seems like a better one.)  For internal use, the Serviceability 
Agent may be your friend.

[Eric Hawkes]
> My question is: is this a bug?  If so, what should be
> done about it?

The JLS doesn't promise that finalize() methods will be run 
promptly.  It does promise that they will be run before the 
storage is reused.  On the other hand, if the storage can't  
be reused because the finalize() methods haven't been run, 
then the collector can't reuse the space and you will run out 
out of memory.  People have suggested that when we run out of 
memory we run the finalize() methods in preference to other 
code, but if the finalize() methods need more memory they 
won't run if we are out of memory.

It's also easy to back up the finalizer queue by having finalize() 
methods that do a lot of work.  If finalize() is more expensive 
than allocation then a program that "just" does allocation 
will back up the finalizer queue.  Since allocation is parallelized 
but finalization isn't (or need not be), running on a multi-processor 
requires that you rethink the relative cost of allocation versus 

--------- End email from Peter Kessler -------------------------

- Eric (###@###.###) 

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mantis mantis-b02 FIXED IN: mantis mantis-b02 INTEGRATED IN: mantis mantis-b02

SUGGESTED FIX The fix is in the attachment (webrev.tar.gz) Here is summary of the fix. -- These are three fixes in one. 1. Stop using finalizers for GapContent (Do not care about StringContent) 2. Stop using finalizers for AbstractElement 3. Stop creating multiple Positions for the same index in GapContent Item [1] GapContent.java Make MarkData WeakReference for StickyPosion Item [3] GapContent.java 222 search.index = index; 223 int sortIndex = findSortIndex(search); 224 MarkData m; 225 StickyPosition position; 226 if (sortIndex < marks.size() 227 && (m = marks.elementAt(sortIndex)).index == index 228 && (position = m.getPosition()) != null) { 229 //position references the correct StickyPostition 230 } else { 231 position = new StickyPosition(); 232 m = new MarkData(index,position,queue); 233 position.setMark(m); 234 marks.insertElementAt(m, sortIndex); 235 } 236 237 return position; In case we have MarkData for the index return Position referred by this MarkData. Item [2] AbstracElement.java remove finalize method. StyleContext.java Use WeakHashMap for attributesPool instead of using Hashtable. --

EVALUATION The only place we are using finalizers is in the text package (SwingGraphics uses it too, but SwingGraphics isn't used anymore). ###@###.### 2002-05-06 ----- I will remove finlizers from GapContent.java and AbstractDocumet.java for the last one I have to submit CCC request Suggested fix is in the attachment (webrev.tar.gz) ###@###.### 2002-06-14